struct nf_conntrack_tuple otuple, rtuple;
struct nf_conntrack_zone ct_zone;
struct nf_conn *ct;
+ u8 ct_zone_dir = 0;
+ u16 ct_zone_id;
+ s32 netns_id;
+ u8 l4proto;
int err;
if (!(opts_len == NF_BPF_CT_OPTS_SZ || opts_len == 12))
return ERR_PTR(-EINVAL);
+
+ netns_id = READ_ONCE(opts->netns_id);
+ l4proto = READ_ONCE(opts->l4proto);
+ ct_zone_id = READ_ONCE(opts->ct_zone_id);
if (opts_len == NF_BPF_CT_OPTS_SZ) {
- if (opts->reserved[0] || opts->reserved[1] || opts->reserved[2])
+ ct_zone_dir = READ_ONCE(opts->ct_zone_dir);
+ if (READ_ONCE(opts->reserved[0]) ||
+ READ_ONCE(opts->reserved[1]) ||
+ READ_ONCE(opts->reserved[2]))
return ERR_PTR(-EINVAL);
} else {
- if (opts->ct_zone_id)
+ if (ct_zone_id)
return ERR_PTR(-EINVAL);
}
- if (unlikely(opts->netns_id < BPF_F_CURRENT_NETNS))
+ if (unlikely(netns_id < BPF_F_CURRENT_NETNS))
return ERR_PTR(-EINVAL);
- err = bpf_nf_ct_tuple_parse(bpf_tuple, tuple_len, opts->l4proto,
+ err = bpf_nf_ct_tuple_parse(bpf_tuple, tuple_len, l4proto,
IP_CT_DIR_ORIGINAL, &otuple);
if (err < 0)
return ERR_PTR(err);
- err = bpf_nf_ct_tuple_parse(bpf_tuple, tuple_len, opts->l4proto,
+ err = bpf_nf_ct_tuple_parse(bpf_tuple, tuple_len, l4proto,
IP_CT_DIR_REPLY, &rtuple);
if (err < 0)
return ERR_PTR(err);
- if (opts->netns_id >= 0) {
- net = get_net_ns_by_id(net, opts->netns_id);
+ if (netns_id >= 0) {
+ net = get_net_ns_by_id(net, netns_id);
if (unlikely(!net))
return ERR_PTR(-ENONET);
}
if (opts_len == NF_BPF_CT_OPTS_SZ) {
- if (opts->ct_zone_dir == 0)
- opts->ct_zone_dir = NF_CT_DEFAULT_ZONE_DIR;
- nf_ct_zone_init(&ct_zone,
- opts->ct_zone_id, opts->ct_zone_dir, 0);
+ if (ct_zone_dir == 0) {
+ ct_zone_dir = NF_CT_DEFAULT_ZONE_DIR;
+ opts->ct_zone_dir = ct_zone_dir;
+ }
+ nf_ct_zone_init(&ct_zone, ct_zone_id, ct_zone_dir, 0);
} else {
ct_zone = nf_ct_zone_dflt;
}
__nf_ct_set_timeout(ct, timeout * HZ);
out:
- if (opts->netns_id >= 0)
+ if (netns_id >= 0)
put_net(net);
return ct;
struct nf_conntrack_tuple tuple;
struct nf_conntrack_zone ct_zone;
struct nf_conn *ct;
+ u8 ct_zone_dir = 0;
+ u16 ct_zone_id;
+ s32 netns_id;
+ u8 l4proto;
int err;
if (!opts || !bpf_tuple)
return ERR_PTR(-EINVAL);
if (!(opts_len == NF_BPF_CT_OPTS_SZ || opts_len == 12))
return ERR_PTR(-EINVAL);
+
+ netns_id = READ_ONCE(opts->netns_id);
+ l4proto = READ_ONCE(opts->l4proto);
+ ct_zone_id = READ_ONCE(opts->ct_zone_id);
if (opts_len == NF_BPF_CT_OPTS_SZ) {
- if (opts->reserved[0] || opts->reserved[1] || opts->reserved[2])
+ ct_zone_dir = READ_ONCE(opts->ct_zone_dir);
+ if (READ_ONCE(opts->reserved[0]) ||
+ READ_ONCE(opts->reserved[1]) ||
+ READ_ONCE(opts->reserved[2]))
return ERR_PTR(-EINVAL);
} else {
- if (opts->ct_zone_id)
+ if (ct_zone_id)
return ERR_PTR(-EINVAL);
}
- if (unlikely(opts->l4proto != IPPROTO_TCP && opts->l4proto != IPPROTO_UDP))
+ if (unlikely(l4proto != IPPROTO_TCP && l4proto != IPPROTO_UDP))
return ERR_PTR(-EPROTO);
- if (unlikely(opts->netns_id < BPF_F_CURRENT_NETNS))
+ if (unlikely(netns_id < BPF_F_CURRENT_NETNS))
return ERR_PTR(-EINVAL);
- err = bpf_nf_ct_tuple_parse(bpf_tuple, tuple_len, opts->l4proto,
+ err = bpf_nf_ct_tuple_parse(bpf_tuple, tuple_len, l4proto,
IP_CT_DIR_ORIGINAL, &tuple);
if (err < 0)
return ERR_PTR(err);
- if (opts->netns_id >= 0) {
- net = get_net_ns_by_id(net, opts->netns_id);
+ if (netns_id >= 0) {
+ net = get_net_ns_by_id(net, netns_id);
if (unlikely(!net))
return ERR_PTR(-ENONET);
}
if (opts_len == NF_BPF_CT_OPTS_SZ) {
- if (opts->ct_zone_dir == 0)
- opts->ct_zone_dir = NF_CT_DEFAULT_ZONE_DIR;
- nf_ct_zone_init(&ct_zone,
- opts->ct_zone_id, opts->ct_zone_dir, 0);
+ if (ct_zone_dir == 0) {
+ ct_zone_dir = NF_CT_DEFAULT_ZONE_DIR;
+ opts->ct_zone_dir = ct_zone_dir;
+ }
+ nf_ct_zone_init(&ct_zone, ct_zone_id, ct_zone_dir, 0);
} else {
ct_zone = nf_ct_zone_dflt;
}
hash = nf_conntrack_find_get(net, &ct_zone, &tuple);
- if (opts->netns_id >= 0)
+ if (netns_id >= 0)
put_net(net);
if (!hash)
return ERR_PTR(-ENOENT);