Lines Matching +full:conntrack +full:- +full:related

1 // SPDX-License-Identifier: GPL-2.0-only
33 #include "conntrack.h"
42 /* Metadata mark for masked write to conntrack mark */
48 /* Metadata label for masked write to conntrack label. */
60 /* Conntrack action context for execution. */
87 /* Elements in ovs_ct_limit_info->limits hash table */
111 switch (ntohs(key->eth.type)) { in key_to_nfproto()
157 return ct ? READ_ONCE(ct->mark) : 0; in ovs_ct_get_mark()
163 /* Guard against conntrack labels max size shrinking below 128 bits. */
174 memcpy(labels, cl->bits, OVS_CT_LABELS_LEN); in ovs_ct_get_labels()
183 key->ct_orig_proto = orig->dst.protonum; in __ovs_ct_update_key_orig_tp()
184 if (orig->dst.protonum == icmp_proto) { in __ovs_ct_update_key_orig_tp()
185 key->ct.orig_tp.src = htons(orig->dst.u.icmp.type); in __ovs_ct_update_key_orig_tp()
186 key->ct.orig_tp.dst = htons(orig->dst.u.icmp.code); in __ovs_ct_update_key_orig_tp()
188 key->ct.orig_tp.src = orig->src.u.all; in __ovs_ct_update_key_orig_tp()
189 key->ct.orig_tp.dst = orig->dst.u.all; in __ovs_ct_update_key_orig_tp()
197 key->ct_state = state; in __ovs_ct_update_key()
198 key->ct_zone = zone->id; in __ovs_ct_update_key()
199 key->ct.mark = ovs_ct_get_mark(ct); in __ovs_ct_update_key()
200 ovs_ct_get_labels(ct, &key->ct.labels); in __ovs_ct_update_key()
206 if (ct->master) in __ovs_ct_update_key()
207 ct = ct->master; in __ovs_ct_update_key()
208 orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; in __ovs_ct_update_key()
211 if (key->eth.type == htons(ETH_P_IP) && in __ovs_ct_update_key()
213 key->ipv4.ct_orig.src = orig->src.u3.ip; in __ovs_ct_update_key()
214 key->ipv4.ct_orig.dst = orig->dst.u3.ip; in __ovs_ct_update_key()
217 } else if (key->eth.type == htons(ETH_P_IPV6) && in __ovs_ct_update_key()
220 key->ipv6.ct_orig.src = orig->src.u3.in6; in __ovs_ct_update_key()
221 key->ipv6.ct_orig.dst = orig->dst.u3.in6; in __ovs_ct_update_key()
226 /* Clear 'ct_orig_proto' to mark the non-existence of conntrack in __ovs_ct_update_key()
229 key->ct_orig_proto = 0; in __ovs_ct_update_key()
232 /* Update 'key' based on skb->_nfct. If 'post_ct' is true, then OVS has
233 * previously sent the packet to conntrack via the ct action. If
253 /* OVS persists the related flag for the duration of the in ovs_ct_update_key()
256 if (ct->master) in ovs_ct_update_key()
259 state |= key->ct_state & OVS_CS_F_NAT_MASK; in ovs_ct_update_key()
261 if (ct->status & IPS_SRC_NAT) in ovs_ct_update_key()
263 if (ct->status & IPS_DST_NAT) in ovs_ct_update_key()
270 zone = &info->zone; in ovs_ct_update_key()
288 if (nla_put_u32(skb, OVS_KEY_ATTR_CT_STATE, output->ct_state)) in ovs_ct_put_key()
289 return -EMSGSIZE; in ovs_ct_put_key()
292 nla_put_u16(skb, OVS_KEY_ATTR_CT_ZONE, output->ct_zone)) in ovs_ct_put_key()
293 return -EMSGSIZE; in ovs_ct_put_key()
296 nla_put_u32(skb, OVS_KEY_ATTR_CT_MARK, output->ct.mark)) in ovs_ct_put_key()
297 return -EMSGSIZE; in ovs_ct_put_key()
300 nla_put(skb, OVS_KEY_ATTR_CT_LABELS, sizeof(output->ct.labels), in ovs_ct_put_key()
301 &output->ct.labels)) in ovs_ct_put_key()
302 return -EMSGSIZE; in ovs_ct_put_key()
304 if (swkey->ct_orig_proto) { in ovs_ct_put_key()
305 if (swkey->eth.type == htons(ETH_P_IP)) { in ovs_ct_put_key()
309 orig.ipv4_src = output->ipv4.ct_orig.src; in ovs_ct_put_key()
310 orig.ipv4_dst = output->ipv4.ct_orig.dst; in ovs_ct_put_key()
311 orig.src_port = output->ct.orig_tp.src; in ovs_ct_put_key()
312 orig.dst_port = output->ct.orig_tp.dst; in ovs_ct_put_key()
313 orig.ipv4_proto = output->ct_orig_proto; in ovs_ct_put_key()
317 return -EMSGSIZE; in ovs_ct_put_key()
318 } else if (swkey->eth.type == htons(ETH_P_IPV6)) { in ovs_ct_put_key()
322 memcpy(orig.ipv6_src, output->ipv6.ct_orig.src.s6_addr32, in ovs_ct_put_key()
324 memcpy(orig.ipv6_dst, output->ipv6.ct_orig.dst.s6_addr32, in ovs_ct_put_key()
326 orig.src_port = output->ct.orig_tp.src; in ovs_ct_put_key()
327 orig.dst_port = output->ct.orig_tp.dst; in ovs_ct_put_key()
328 orig.ipv6_proto = output->ct_orig_proto; in ovs_ct_put_key()
332 return -EMSGSIZE; in ovs_ct_put_key()
345 new_mark = ct_mark | (READ_ONCE(ct->mark) & ~(mask)); in ovs_ct_set_mark()
346 if (READ_ONCE(ct->mark) != new_mark) { in ovs_ct_set_mark()
347 WRITE_ONCE(ct->mark, new_mark); in ovs_ct_set_mark()
350 key->ct.mark = new_mark; in ovs_ct_set_mark()
355 return -ENOTSUPP; in ovs_ct_set_mark()
372 /* Initialize labels for a new, yet to be committed conntrack entry. Note that
373 * since the new connection is not yet confirmed, and thus no-one else has
383 /* Inherit master's labels to the related connection? */ in ovs_ct_init_labels()
384 master_cl = ct->master ? nf_ct_labels_find(ct->master) : NULL; in ovs_ct_init_labels()
391 return -ENOSPC; in ovs_ct_init_labels()
398 u32 *dst = (u32 *)cl->bits; in ovs_ct_init_labels()
402 dst[i] = (dst[i] & ~mask->ct_labels_32[i]) | in ovs_ct_init_labels()
403 (labels->ct_labels_32[i] in ovs_ct_init_labels()
404 & mask->ct_labels_32[i]); in ovs_ct_init_labels()
412 memcpy(&key->ct.labels, cl->bits, OVS_CT_LABELS_LEN); in ovs_ct_init_labels()
426 return -ENOSPC; in ovs_ct_set_labels()
428 err = nf_connlabels_replace(ct, labels->ct_labels_32, in ovs_ct_set_labels()
429 mask->ct_labels_32, in ovs_ct_set_labels()
434 memcpy(&key->ct.labels, cl->bits, OVS_CT_LABELS_LEN); in ovs_ct_set_labels()
445 err = nf_ct_handle_fragments(net, skb, zone, family, &key->ip.proto, &ovs_cb.mru); in ovs_ct_handle_fragments()
453 key->ip.frag = OVS_FRAG_TYPE_NONE; in ovs_ct_handle_fragments()
468 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) in ovs_ct_get_info()
470 if (test_bit(IPS_EXPECTED_BIT, &ct->status)) in ovs_ct_get_info()
476 * re-attributing statistics or modifying the connection state. This allows an
477 * skb->_nfct lost due to an upcall to be recovered during actions execution.
481 * On success, populates skb->_nfct and returns the connection. Returns NULL
516 /* Inverted packet tuple matches the reverse direction conntrack tuple, in ovs_ct_find_existing()
521 h = &ct->tuplehash[!h->tuple.dst.dir]; in ovs_ct_find_existing()
536 /* If no ct, check if we have evidence that an existing conntrack entry in ovs_ct_executed()
537 * might be found for this skb. This happens when we lose a skb->_nfct in ovs_ct_executed()
540 * through conntrack again. in ovs_ct_executed()
542 *ct_executed = (key->ct_state & OVS_CS_F_TRACKED) && in ovs_ct_executed()
543 !(key->ct_state & OVS_CS_F_INVALID) && in ovs_ct_executed()
544 (key->ct_zone == info->zone.id); in ovs_ct_executed()
546 if (*ct_executed || (!key->ct_state && info->force)) { in ovs_ct_executed()
547 ct = ovs_ct_find_existing(net, &info->zone, info->family, skb, in ovs_ct_executed()
548 !!(key->ct_state & in ovs_ct_executed()
555 /* Determine whether skb->_nfct is equal to the result of conntrack lookup. */
574 if (!net_eq(net, read_pnet(&ct->ct_net))) in skb_nfct_cached()
576 if (!nf_ct_zone_equal_any(info->ct, nf_ct_zone(ct))) in skb_nfct_cached()
578 if (info->helper) { in skb_nfct_cached()
582 if (help && rcu_access_pointer(help->helper) != info->helper) in skb_nfct_cached()
585 if (info->nf_ct_timeout) { in skb_nfct_cached()
589 if (!timeout_ext || info->nf_ct_timeout != in skb_nfct_cached()
590 rcu_dereference(timeout_ext->timeout)) in skb_nfct_cached()
593 /* Force conntrack entry direction to the current packet? */ in skb_nfct_cached()
594 if (info->force && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { in skb_nfct_cached()
595 /* Delete the conntrack entry if confirmed, else just release in skb_nfct_cached()
617 key->ct_state |= OVS_CS_F_SRC_NAT; in ovs_nat_update_key()
618 if (key->eth.type == htons(ETH_P_IP)) in ovs_nat_update_key()
619 key->ipv4.addr.src = ip_hdr(skb)->saddr; in ovs_nat_update_key()
620 else if (key->eth.type == htons(ETH_P_IPV6)) in ovs_nat_update_key()
621 memcpy(&key->ipv6.addr.src, &ipv6_hdr(skb)->saddr, in ovs_nat_update_key()
622 sizeof(key->ipv6.addr.src)); in ovs_nat_update_key()
626 if (key->ip.proto == IPPROTO_UDP) in ovs_nat_update_key()
627 src = udp_hdr(skb)->source; in ovs_nat_update_key()
628 else if (key->ip.proto == IPPROTO_TCP) in ovs_nat_update_key()
629 src = tcp_hdr(skb)->source; in ovs_nat_update_key()
630 else if (key->ip.proto == IPPROTO_SCTP) in ovs_nat_update_key()
631 src = sctp_hdr(skb)->source; in ovs_nat_update_key()
635 key->tp.src = src; in ovs_nat_update_key()
639 key->ct_state |= OVS_CS_F_DST_NAT; in ovs_nat_update_key()
640 if (key->eth.type == htons(ETH_P_IP)) in ovs_nat_update_key()
641 key->ipv4.addr.dst = ip_hdr(skb)->daddr; in ovs_nat_update_key()
642 else if (key->eth.type == htons(ETH_P_IPV6)) in ovs_nat_update_key()
643 memcpy(&key->ipv6.addr.dst, &ipv6_hdr(skb)->daddr, in ovs_nat_update_key()
644 sizeof(key->ipv6.addr.dst)); in ovs_nat_update_key()
648 if (key->ip.proto == IPPROTO_UDP) in ovs_nat_update_key()
649 dst = udp_hdr(skb)->dest; in ovs_nat_update_key()
650 else if (key->ip.proto == IPPROTO_TCP) in ovs_nat_update_key()
651 dst = tcp_hdr(skb)->dest; in ovs_nat_update_key()
652 else if (key->ip.proto == IPPROTO_SCTP) in ovs_nat_update_key()
653 dst = sctp_hdr(skb)->dest; in ovs_nat_update_key()
657 key->tp.dst = dst; in ovs_nat_update_key()
669 if (!(info->nat & OVS_CT_NAT)) in ovs_ct_nat()
671 if (info->nat & OVS_CT_SRC_NAT) in ovs_ct_nat()
673 if (info->nat & OVS_CT_DST_NAT) in ovs_ct_nat()
676 err = nf_ct_nat(skb, ct, ctinfo, &action, &info->range, info->commit); in ovs_ct_nat()
695 /* Pass 'skb' through conntrack in 'net', using zone configured in 'info', if
697 * through conntrack.
698 * Note that if the packet is deemed invalid by conntrack, skb->_nfct will be
705 /* If we are recirculating packets to match on conntrack fields and in __ovs_ct_lookup()
706 * committing with a separate conntrack action, then we don't need to in __ovs_ct_lookup()
707 * actually run the packet through conntrack twice unless it's for a in __ovs_ct_lookup()
717 .pf = info->family, in __ovs_ct_lookup()
720 struct nf_conn *tmpl = info->ct; in __ovs_ct_lookup()
727 nf_conntrack_get(&tmpl->ct_general); in __ovs_ct_lookup()
733 return -ENOENT; in __ovs_ct_lookup()
737 * the whole state, as it will be re-initialized below. in __ovs_ct_lookup()
739 key->ct_state = 0; in __ovs_ct_lookup()
757 * the key->ct_state. in __ovs_ct_lookup()
759 if (info->nat && !(key->ct_state & OVS_CS_F_NAT_MASK) && in __ovs_ct_lookup()
760 (nf_ct_is_confirmed(ct) || info->commit) && in __ovs_ct_lookup()
762 return -EINVAL; in __ovs_ct_lookup()
771 if (!nf_ct_is_confirmed(ct) && info->commit && in __ovs_ct_lookup()
772 info->helper && !nfct_help(ct)) { in __ovs_ct_lookup()
773 int err = __nf_ct_try_assign_helper(ct, info->ct, in __ovs_ct_lookup()
780 if (info->nat && !nfct_seqadj(ct)) { in __ovs_ct_lookup()
782 return -EINVAL; in __ovs_ct_lookup()
787 * - nf_conntrack_in() was executed above ("!cached") or a in __ovs_ct_lookup()
790 * - When committing an unconfirmed connection. in __ovs_ct_lookup()
793 info->commit) && in __ovs_ct_lookup()
794 nf_ct_helper(skb, ct, ctinfo, info->family) != NF_ACCEPT) { in __ovs_ct_lookup()
795 return -EINVAL; in __ovs_ct_lookup()
800 /* Be liberal for tcp packets so that out-of-window in __ovs_ct_lookup()
836 if (labels->ct_labels_32[i]) in labels_nonzero()
846 return &info->limits[zone & (CT_LIMIT_HASH_BUCKETS - 1)]; in ct_limit_hash_bucket()
856 head = ct_limit_hash_bucket(info, new_ct_limit->zone); in ct_limit_set()
858 if (ct_limit->zone == new_ct_limit->zone) { in ct_limit_set()
859 hlist_replace_rcu(&ct_limit->hlist_node, in ct_limit_set()
860 &new_ct_limit->hlist_node); in ct_limit_set()
866 hlist_add_head_rcu(&new_ct_limit->hlist_node, head); in ct_limit_set()
878 if (ct_limit->zone == zone) { in ct_limit_del()
879 hlist_del_rcu(&ct_limit->hlist_node); in ct_limit_del()
894 if (ct_limit->zone == zone) in ct_limit_get()
895 return ct_limit->limit; in ct_limit_get()
898 return info->default_limit; in ct_limit_get()
906 const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; in ovs_ct_check_limit()
910 conncount_key = info->zone.id; in ovs_ct_check_limit()
912 per_zone_limit = ct_limit_get(ct_limit_info, info->zone.id); in ovs_ct_check_limit()
916 connections = nf_conncount_count(net, ct_limit_info->data, in ovs_ct_check_limit()
917 &conncount_key, tuple, &info->zone); in ovs_ct_check_limit()
919 return -ENOMEM; in ovs_ct_check_limit()
938 /* The connection could be invalid, in which case this is a no-op.*/ in ovs_ct_commit()
947 &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); in ovs_ct_commit()
950 "exceeds conntrack limit\n", in ovs_ct_commit()
951 info->zone.id); in ovs_ct_commit()
958 /* Set the conntrack event mask if given. NEW and DELETE events have in ovs_ct_commit()
965 if (info->have_eventmask) { in ovs_ct_commit()
969 cache->ctmask = info->eventmask; in ovs_ct_commit()
973 * conntrack NEW netlink event carries the values given in the CT in ovs_ct_commit()
976 if (info->mark.mask) { in ovs_ct_commit()
977 err = ovs_ct_set_mark(ct, key, info->mark.value, in ovs_ct_commit()
978 info->mark.mask); in ovs_ct_commit()
983 err = ovs_ct_init_labels(ct, key, &info->labels.value, in ovs_ct_commit()
984 &info->labels.mask); in ovs_ct_commit()
990 labels_nonzero(&info->labels.mask)) { in ovs_ct_commit()
991 err = ovs_ct_set_labels(ct, key, &info->labels.value, in ovs_ct_commit()
992 &info->labels.mask); in ovs_ct_commit()
1000 return -EINVAL; in ovs_ct_commit()
1005 /* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero
1015 /* The conntrack module expects to be working at L3. */ in ovs_ct_execute()
1019 err = nf_ct_skb_network_trim(skb, info->family); in ovs_ct_execute()
1025 if (key->ip.frag != OVS_FRAG_TYPE_NONE) { in ovs_ct_execute()
1026 err = ovs_ct_handle_fragments(net, key, info->zone.id, in ovs_ct_execute()
1027 info->family, skb); in ovs_ct_execute()
1032 if (info->commit) in ovs_ct_execute()
1067 bool ip_vers = (info->family == NFPROTO_IPV6); in parse_nat()
1088 return -EINVAL; in parse_nat()
1095 return -EINVAL; in parse_nat()
1101 if (info->nat) { in parse_nat()
1103 return -ERANGE; in parse_nat()
1105 info->nat |= OVS_CT_NAT; in parse_nat()
1106 info->nat |= ((type == OVS_NAT_ATTR_SRC) in parse_nat()
1111 nla_memcpy(&info->range.min_addr, a, in parse_nat()
1112 sizeof(info->range.min_addr)); in parse_nat()
1113 info->range.flags |= NF_NAT_RANGE_MAP_IPS; in parse_nat()
1118 nla_memcpy(&info->range.max_addr, a, in parse_nat()
1119 sizeof(info->range.max_addr)); in parse_nat()
1120 info->range.flags |= NF_NAT_RANGE_MAP_IPS; in parse_nat()
1124 info->range.min_proto.all = htons(nla_get_u16(a)); in parse_nat()
1125 info->range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; in parse_nat()
1130 info->range.max_proto.all = htons(nla_get_u16(a)); in parse_nat()
1131 info->range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; in parse_nat()
1135 info->range.flags |= NF_NAT_RANGE_PERSISTENT; in parse_nat()
1139 info->range.flags |= NF_NAT_RANGE_PROTO_RANDOM; in parse_nat()
1143 info->range.flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; in parse_nat()
1148 return -EINVAL; in parse_nat()
1154 return -EINVAL; in parse_nat()
1156 if (!info->nat) { in parse_nat()
1158 if (info->range.flags) { in parse_nat()
1162 return -EINVAL; in parse_nat()
1164 info->nat = OVS_CT_NAT; /* NAT existing connections. */ in parse_nat()
1165 } else if (!info->commit) { in parse_nat()
1169 return -EINVAL; in parse_nat()
1172 if (info->range.flags & NF_NAT_RANGE_MAP_IPS && !have_ip_max) { in parse_nat()
1173 memcpy(&info->range.max_addr, &info->range.min_addr, in parse_nat()
1174 sizeof(info->range.max_addr)); in parse_nat()
1177 if (info->range.flags & NF_NAT_RANGE_PROTO_SPECIFIED && in parse_nat()
1179 info->range.max_proto.all = info->range.min_proto.all; in parse_nat()
1219 "Unknown conntrack attr (type=%d, max=%d)", in parse_ct()
1221 return -EINVAL; in parse_ct()
1228 "Conntrack attr type has unexpected length (type=%d, length=%d, expected=%d)", in parse_ct()
1230 return -EINVAL; in parse_ct()
1235 info->force = true; in parse_ct()
1238 info->commit = true; in parse_ct()
1242 info->zone.id = nla_get_u16(a); in parse_ct()
1249 if (!mark->mask) { in parse_ct()
1251 return -EINVAL; in parse_ct()
1253 info->mark = *mark; in parse_ct()
1261 if (!labels_nonzero(&labels->mask)) { in parse_ct()
1263 return -EINVAL; in parse_ct()
1265 info->labels = *labels; in parse_ct()
1272 OVS_NLERR(log, "Invalid conntrack helper"); in parse_ct()
1273 return -EINVAL; in parse_ct()
1286 info->have_eventmask = true; in parse_ct()
1287 info->eventmask = nla_get_u32(a); in parse_ct()
1291 memcpy(info->timeout, nla_data(a), nla_len(a)); in parse_ct()
1292 if (!string_is_terminated(info->timeout, nla_len(a))) { in parse_ct()
1293 OVS_NLERR(log, "Invalid conntrack timeout"); in parse_ct()
1294 return -EINVAL; in parse_ct()
1300 OVS_NLERR(log, "Unknown conntrack attr (%d)", in parse_ct()
1302 return -EINVAL; in parse_ct()
1307 if (!info->commit && info->mark.mask) { in parse_ct()
1309 "Setting conntrack mark requires 'commit' flag."); in parse_ct()
1310 return -EINVAL; in parse_ct()
1314 if (!info->commit && labels_nonzero(&info->labels.mask)) { in parse_ct()
1316 "Setting conntrack labels requires 'commit' flag."); in parse_ct()
1317 return -EINVAL; in parse_ct()
1321 OVS_NLERR(log, "Conntrack attr has %d unknown bytes", rem); in parse_ct()
1322 return -EINVAL; in parse_ct()
1342 return ovs_net->xt_label; in ovs_ct_verify()
1360 return -EINVAL; in ovs_ct_copy_action()
1376 OVS_NLERR(log, "Failed to allocate conntrack template"); in ovs_ct_copy_action()
1377 return -ENOMEM; in ovs_ct_copy_action()
1381 if (nf_ct_set_timeout(net, ct_info.ct, family, key->ip.proto, in ovs_ct_copy_action()
1387 nf_ct_timeout_find(ct_info.ct)->timeout); in ovs_ct_copy_action()
1393 key->ip.proto, ct_info.nat, &ct_info.helper); in ovs_ct_copy_action()
1406 __set_bit(IPS_CONFIRMED_BIT, &ct_info.ct->status); in ovs_ct_copy_action()
1423 if (info->nat & OVS_CT_SRC_NAT) { in ovs_ct_nat_to_attr()
1426 } else if (info->nat & OVS_CT_DST_NAT) { in ovs_ct_nat_to_attr()
1433 if (info->range.flags & NF_NAT_RANGE_MAP_IPS) { in ovs_ct_nat_to_attr()
1435 info->family == NFPROTO_IPV4) { in ovs_ct_nat_to_attr()
1437 info->range.min_addr.ip) || in ovs_ct_nat_to_attr()
1438 (info->range.max_addr.ip in ovs_ct_nat_to_attr()
1439 != info->range.min_addr.ip && in ovs_ct_nat_to_attr()
1441 info->range.max_addr.ip)))) in ovs_ct_nat_to_attr()
1444 info->family == NFPROTO_IPV6) { in ovs_ct_nat_to_attr()
1446 &info->range.min_addr.in6) || in ovs_ct_nat_to_attr()
1447 (memcmp(&info->range.max_addr.in6, in ovs_ct_nat_to_attr()
1448 &info->range.min_addr.in6, in ovs_ct_nat_to_attr()
1449 sizeof(info->range.max_addr.in6)) && in ovs_ct_nat_to_attr()
1451 &info->range.max_addr.in6)))) in ovs_ct_nat_to_attr()
1457 if (info->range.flags & NF_NAT_RANGE_PROTO_SPECIFIED && in ovs_ct_nat_to_attr()
1459 ntohs(info->range.min_proto.all)) || in ovs_ct_nat_to_attr()
1460 (info->range.max_proto.all != info->range.min_proto.all && in ovs_ct_nat_to_attr()
1462 ntohs(info->range.max_proto.all))))) in ovs_ct_nat_to_attr()
1465 if (info->range.flags & NF_NAT_RANGE_PERSISTENT && in ovs_ct_nat_to_attr()
1468 if (info->range.flags & NF_NAT_RANGE_PROTO_RANDOM && in ovs_ct_nat_to_attr()
1471 if (info->range.flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY && in ovs_ct_nat_to_attr()
1488 return -EMSGSIZE; in ovs_ct_action_to_attr()
1490 if (ct_info->commit && nla_put_flag(skb, ct_info->force in ovs_ct_action_to_attr()
1493 return -EMSGSIZE; in ovs_ct_action_to_attr()
1495 nla_put_u16(skb, OVS_CT_ATTR_ZONE, ct_info->zone.id)) in ovs_ct_action_to_attr()
1496 return -EMSGSIZE; in ovs_ct_action_to_attr()
1497 if (IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) && ct_info->mark.mask && in ovs_ct_action_to_attr()
1498 nla_put(skb, OVS_CT_ATTR_MARK, sizeof(ct_info->mark), in ovs_ct_action_to_attr()
1499 &ct_info->mark)) in ovs_ct_action_to_attr()
1500 return -EMSGSIZE; in ovs_ct_action_to_attr()
1502 labels_nonzero(&ct_info->labels.mask) && in ovs_ct_action_to_attr()
1503 nla_put(skb, OVS_CT_ATTR_LABELS, sizeof(ct_info->labels), in ovs_ct_action_to_attr()
1504 &ct_info->labels)) in ovs_ct_action_to_attr()
1505 return -EMSGSIZE; in ovs_ct_action_to_attr()
1506 if (ct_info->helper) { in ovs_ct_action_to_attr()
1508 ct_info->helper->name)) in ovs_ct_action_to_attr()
1509 return -EMSGSIZE; in ovs_ct_action_to_attr()
1511 if (ct_info->have_eventmask && in ovs_ct_action_to_attr()
1512 nla_put_u32(skb, OVS_CT_ATTR_EVENTMASK, ct_info->eventmask)) in ovs_ct_action_to_attr()
1513 return -EMSGSIZE; in ovs_ct_action_to_attr()
1514 if (ct_info->timeout[0]) { in ovs_ct_action_to_attr()
1515 if (nla_put_string(skb, OVS_CT_ATTR_TIMEOUT, ct_info->timeout)) in ovs_ct_action_to_attr()
1516 return -EMSGSIZE; in ovs_ct_action_to_attr()
1520 if (ct_info->nat && !ovs_ct_nat_to_attr(ct_info, skb)) in ovs_ct_action_to_attr()
1521 return -EMSGSIZE; in ovs_ct_action_to_attr()
1537 if (ct_info->helper) { in __ovs_ct_free_action()
1539 if (ct_info->nat) in __ovs_ct_free_action()
1540 nf_nat_helper_put(ct_info->helper); in __ovs_ct_free_action()
1542 nf_conntrack_helper_put(ct_info->helper); in __ovs_ct_free_action()
1544 if (ct_info->ct) { in __ovs_ct_free_action()
1545 if (ct_info->timeout[0]) in __ovs_ct_free_action()
1546 nf_ct_destroy_timeout(ct_info->ct); in __ovs_ct_free_action()
1547 nf_ct_tmpl_free(ct_info->ct); in __ovs_ct_free_action()
1556 ovs_net->ct_limit_info = kmalloc(sizeof(*ovs_net->ct_limit_info), in ovs_ct_limit_init()
1558 if (!ovs_net->ct_limit_info) in ovs_ct_limit_init()
1559 return -ENOMEM; in ovs_ct_limit_init()
1561 ovs_net->ct_limit_info->default_limit = OVS_CT_LIMIT_DEFAULT; in ovs_ct_limit_init()
1562 ovs_net->ct_limit_info->limits = in ovs_ct_limit_init()
1565 if (!ovs_net->ct_limit_info->limits) { in ovs_ct_limit_init()
1566 kfree(ovs_net->ct_limit_info); in ovs_ct_limit_init()
1567 return -ENOMEM; in ovs_ct_limit_init()
1571 INIT_HLIST_HEAD(&ovs_net->ct_limit_info->limits[i]); in ovs_ct_limit_init()
1573 ovs_net->ct_limit_info->data = in ovs_ct_limit_init()
1576 if (IS_ERR(ovs_net->ct_limit_info->data)) { in ovs_ct_limit_init()
1577 err = PTR_ERR(ovs_net->ct_limit_info->data); in ovs_ct_limit_init()
1578 kfree(ovs_net->ct_limit_info->limits); in ovs_ct_limit_init()
1579 kfree(ovs_net->ct_limit_info); in ovs_ct_limit_init()
1588 const struct ovs_ct_limit_info *info = ovs_net->ct_limit_info; in ovs_ct_limit_exit()
1591 nf_conncount_destroy(net, NFPROTO_INET, info->data); in ovs_ct_limit_exit()
1593 struct hlist_head *head = &info->limits[i]; in ovs_ct_limit_exit()
1600 kfree(info->limits); in ovs_ct_limit_exit()
1613 return ERR_PTR(-ENOMEM); in ovs_ct_limit_cmd_reply_start()
1615 *ovs_reply_header = genlmsg_put(skb, info->snd_portid, in ovs_ct_limit_cmd_reply_start()
1616 info->snd_seq, in ovs_ct_limit_cmd_reply_start()
1621 return ERR_PTR(-EMSGSIZE); in ovs_ct_limit_cmd_reply_start()
1623 (*ovs_reply_header)->dp_ifindex = ovs_header->dp_ifindex; in ovs_ct_limit_cmd_reply_start()
1648 if (unlikely(zone_limit->zone_id == in ovs_ct_limit_set_zone_limit()
1651 info->default_limit = zone_limit->limit; in ovs_ct_limit_set_zone_limit()
1654 zone_limit->zone_id, &zone))) { in ovs_ct_limit_set_zone_limit()
1662 return -ENOMEM; in ovs_ct_limit_set_zone_limit()
1664 ct_limit->zone = zone; in ovs_ct_limit_set_zone_limit()
1665 ct_limit->limit = zone_limit->limit; in ovs_ct_limit_set_zone_limit()
1671 rem -= NLA_ALIGN(sizeof(*zone_limit)); in ovs_ct_limit_set_zone_limit()
1693 if (unlikely(zone_limit->zone_id == in ovs_ct_limit_del_zone_limit()
1696 info->default_limit = OVS_CT_LIMIT_DEFAULT; in ovs_ct_limit_del_zone_limit()
1699 zone_limit->zone_id, &zone))) { in ovs_ct_limit_del_zone_limit()
1706 rem -= NLA_ALIGN(sizeof(*zone_limit)); in ovs_ct_limit_del_zone_limit()
1722 .limit = info->default_limit, in ovs_ct_limit_get_default_limit()
1760 if (unlikely(zone_limit->zone_id == in ovs_ct_limit_get_zone_limit()
1765 } else if (unlikely(!check_zone_id(zone_limit->zone_id, in ovs_ct_limit_get_zone_limit()
1774 net, info->data, zone, limit, reply); in ovs_ct_limit_get_zone_limit()
1778 rem -= NLA_ALIGN(sizeof(*zone_limit)); in ovs_ct_limit_get_zone_limit()
1803 head = &info->limits[i]; in ovs_ct_limit_get_all_zone_limit()
1805 err = __ovs_ct_limit_get_zone_limit(net, info->data, in ovs_ct_limit_get_all_zone_limit()
1806 ct_limit->zone, ct_limit->limit, reply); in ovs_ct_limit_get_all_zone_limit()
1819 struct nlattr **a = info->attrs; in ovs_ct_limit_cmd_set()
1822 struct ovs_net *ovs_net = net_generic(sock_net(skb->sk), ovs_net_id); in ovs_ct_limit_cmd_set()
1823 struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; in ovs_ct_limit_cmd_set()
1832 err = -EINVAL; in ovs_ct_limit_cmd_set()
1853 struct nlattr **a = info->attrs; in ovs_ct_limit_cmd_del()
1856 struct ovs_net *ovs_net = net_generic(sock_net(skb->sk), ovs_net_id); in ovs_ct_limit_cmd_del()
1857 struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; in ovs_ct_limit_cmd_del()
1866 err = -EINVAL; in ovs_ct_limit_cmd_del()
1885 struct nlattr **a = info->attrs; in ovs_ct_limit_cmd_get()
1889 struct net *net = sock_net(skb->sk); in ovs_ct_limit_cmd_get()
1891 struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; in ovs_ct_limit_cmd_get()
1901 err = -EMSGSIZE; in ovs_ct_limit_cmd_get()
1975 if (nf_connlabels_get(net, n_bits - 1)) { in ovs_ct_init()
1976 ovs_net->xt_label = false; in ovs_ct_init()
1979 ovs_net->xt_label = true; in ovs_ct_init()
1997 if (ovs_net->xt_label) in ovs_ct_exit()