> On Mar 3, 2017, at 1:44 PM, Joe Stringer <[email protected]> wrote:
>
>
>
> On 3/03/2017 10:37, "Jarno Rajahalme" <[email protected] <mailto:[email protected]>>
> wrote:
>
>> On Mar 2, 2017, at 5:26 PM, Joe Stringer <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> On 28 February 2017 at 17:17, Jarno Rajahalme <[email protected]
>> <mailto:[email protected]>> wrote:
>>> Upstream commit:
>>>
>>> Refactoring conntrack labels initialization makes changes in later
>>> patches easier to review.
>>>
>>> Signed-off-by: Jarno Rajahalme <[email protected] <mailto:[email protected]>>
>>> Acked-by: Pravin B Shelar <[email protected] <mailto:[email protected]>>
>>> Acked-by: Joe Stringer <[email protected] <mailto:[email protected]>>
>>> Signed-off-by: David S. Miller <[email protected]
>>> <mailto:[email protected]>>
>>>
>>> Signed-off-by: Jarno Rajahalme <[email protected] <mailto:[email protected]>>
>>> ---
>>> datapath/conntrack.c | 113
>>> ++++++++++++++++++++++++++++++---------------------
>>> 1 file changed, 66 insertions(+), 47 deletions(-)
>>>
>>> diff --git a/datapath/conntrack.c b/datapath/conntrack.c
>>> index dacf34c..adc4315 100644
>>> --- a/datapath/conntrack.c
>>> +++ b/datapath/conntrack.c
>>> @@ -243,19 +243,12 @@ int ovs_ct_put_key(const struct sw_flow_key *key,
>>> struct sk_buff *skb)
>>> return 0;
>>> }
>>>
>>> -static int ovs_ct_set_mark(struct sk_buff *skb, struct sw_flow_key *key,
>>> +static int ovs_ct_set_mark(struct nf_conn *ct, struct sw_flow_key *key,
>>> u32 ct_mark, u32 mask)
>>> {
>>> #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
>>> - enum ip_conntrack_info ctinfo;
>>> - struct nf_conn *ct;
>>> u32 new_mark;
>>>
>>> - /* The connection could be invalid, in which case set_mark is
>>> no-op. */
>>> - ct = nf_ct_get(skb, &ctinfo);
>>> - if (!ct)
>>> - return 0;
>>> -
>>> new_mark = ct_mark | (ct->mark & ~(mask));
>>> if (ct->mark != new_mark) {
>>> ct->mark = new_mark;
>>> @@ -270,56 +263,71 @@ static int ovs_ct_set_mark(struct sk_buff *skb,
>>> struct sw_flow_key *key,
>>> #endif
>>> }
>>>
>>> -static int ovs_ct_set_labels(struct sk_buff *skb, struct sw_flow_key *key,
>>> - const struct ovs_key_ct_labels *labels,
>>> - const struct ovs_key_ct_labels *mask)
>>> +static struct nf_conn_labels *ovs_ct_get_conn_labels(struct nf_conn *ct)
>>> {
>>> - enum ip_conntrack_info ctinfo;
>>> struct nf_conn_labels *cl;
>>> - struct nf_conn *ct;
>>> -
>>> - /* The connection could be invalid, in which case set_label is
>>> no-op.*/
>>> - ct = nf_ct_get(skb, &ctinfo);
>>> - if (!ct)
>>> - return 0;
>>>
>>> cl = nf_ct_labels_find(ct);
>>> if (!cl) {
>>> nf_ct_labels_ext_add(ct);
>>> cl = nf_ct_labels_find(ct);
>>> }
>>> + if (cl && ovs_ct_get_labels_len(cl) < OVS_CT_LABELS_LEN)
>>> + return NULL;
>>
>> The above two lines were not introduced in the upstream code. Do you
>> intend to introduce them?
>>
>
> Should have mentioned this in a commit message or in a comment. The inclusion
> of this test is intentional, and the rationale is that it might be possible
> that the kernel is configured with too little space for labels. However, it
> is possible that the way OVS kernel module initializes the number of words in
> labels for older kernels already takes care of this, do you have a take on
> this?
>
> When we compile the out of tree module for a particular kernel, this
> information should be available. I don't think that we try to support
> compiling against one kernel with one definition of the labels length, then
> allow that same module to run on another kernel with a different definition.
> So it should be fine to omit so long as there are still the compile time
> checks.
>
But my understanding is that the compile time checks only apply to newer
kernels, where the available storage for labels is a compile time
configuration, rather than a run-time number of words.
Jarno
>
> Jarno
>
>> For my current working tree for review/build/test, I will drop these lines.
>>
>>> + return cl;
>>> +}
>>> +
>>> +/* Initialize labels for a new, yet to be committed conntrack entry. Note
>>> that
>>> + * since the new connection is not yet confirmed, and thus no-one else has
>>> + * access to it's labels, we simply write them over.
>>> + */
>>> +static int ovs_ct_init_labels(struct nf_conn *ct, struct sw_flow_key *key,
>>> + const struct ovs_key_ct_labels *labels,
>>> + const struct ovs_key_ct_labels *mask)
>>> +{
>>> + struct nf_conn_labels *cl;
>>> + u32 *dst;
>>> + int i;
>>>
>>> - if (!cl || ovs_ct_get_labels_len(cl) < OVS_CT_LABELS_LEN)
>>> + cl = ovs_ct_get_conn_labels(ct);
>>> + if (!cl)
>>> return -ENOSPC;
>>>
>>> - if (nf_ct_is_confirmed(ct)) {
>>> - /* Triggers a change event, which makes sense only for
>>> - * confirmed connections.
>>> - */
>>> - int err = nf_connlabels_replace(ct, labels->ct_labels_32,
>>> - mask->ct_labels_32,
>>> - OVS_CT_LABELS_LEN_32);
>>> - if (err)
>>> - return err;
>>> - } else {
>>> - u32 *dst = (u32 *)cl->bits;
>>> - const u32 *msk = mask->ct_labels_32;
>>> - const u32 *lbl = labels->ct_labels_32;
>>> - int i;
>>> + dst = (u32 *)cl->bits;
>>> + for (i = 0; i < OVS_CT_LABELS_LEN_32; i++)
>>> + dst[i] = (dst[i] & ~mask->ct_labels_32[i]) |
>>> + (labels->ct_labels_32[i] & mask->ct_labels_32[i]);
>>>
>>> - /* No-one else has access to the non-confirmed entry, copy
>>> - * labels over, keeping any bits we are not explicitly
>>> setting.
>>> - */
>>> - for (i = 0; i < OVS_CT_LABELS_LEN_32; i++)
>>> - dst[i] = (dst[i] & ~msk[i]) | (lbl[i] & msk[i]);
>>> + /* Labels are included in the IPCTNL_MSG_CT_NEW event only if the
>>> + * IPCT_LABEL bit it set in the event cache.
>>> + */
>>> + nf_conntrack_event_cache(IPCT_LABEL, ct);
>>>
>>> - /* Labels are included in the IPCTNL_MSG_CT_NEW event only
>>> if
>>> - * the IPCT_LABEL bit it set in the event cache.
>>> - */
>>> - nf_conntrack_event_cache(IPCT_LABEL, ct);
>>> - }
>>> + memcpy(&key->ct.labels, cl->bits, OVS_CT_LABELS_LEN);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int ovs_ct_set_labels(struct nf_conn *ct, struct sw_flow_key *key,
>>> + const struct ovs_key_ct_labels *labels,
>>> + const struct ovs_key_ct_labels *mask)
>>> +{
>>> + struct nf_conn_labels *cl;
>>> + int err;
>>> +
>>> + cl = ovs_ct_get_conn_labels(ct);
>>> + if (!cl)
>>> + return -ENOSPC;
>>> +
>>> + err = nf_connlabels_replace(ct, labels->ct_labels_32,
>>> + mask->ct_labels_32,
>>> + OVS_CT_LABELS_LEN_32);
>>> + if (err)
>>> + return err;
>>> +
>>> + memcpy(&key->ct.labels, cl->bits, OVS_CT_LABELS_LEN);
>>>
>>> - ovs_ct_get_labels(ct, &key->ct.labels);
>>> return 0;
>>> }
>>>
>>> @@ -926,25 +934,36 @@ static int ovs_ct_commit(struct net *net, struct
>>> sw_flow_key *key,
>>> const struct ovs_conntrack_info *info,
>>> struct sk_buff *skb)
>>> {
>>> + enum ip_conntrack_info ctinfo;
>>> + struct nf_conn *ct;
>>> int err;
>>>
>>> err = __ovs_ct_lookup(net, key, info, skb);
>>> if (err)
>>> return err;
>>>
>>> + /* The connection could be invalid, in which case this is a no-op.*/
>>> + ct = nf_ct_get(skb, &ctinfo);
>>> + if (!ct)
>>> + return 0;
>>> +
>>> /* Apply changes before confirming the connection so that the initial
>>> * conntrack NEW netlink event carries the values given in the CT
>>> * action.
>>> */
>>> if (info->mark.mask) {
>>> - err = ovs_ct_set_mark(skb, key, info->mark.value,
>>> + err = ovs_ct_set_mark(ct, key, info->mark.value,
>>> info->mark.mask);
>>> if (err)
>>> return err;
>>> }
>>> if (labels_nonzero(&info->labels.mask)) {
>>> - err = ovs_ct_set_labels(skb, key, &info->labels.value,
>>> - &info->labels.mask);
>>> + if (!nf_ct_is_confirmed(ct))
>>> + err = ovs_ct_init_labels(ct, key,
>>> &info->labels.value,
>>> + &info->labels.mask);
>>> + else
>>> + err = ovs_ct_set_labels(ct, key,
>>> &info->labels.value,
>>> + &info->labels.mask);
>>> if (err)
>>> return err;
>>> }
>>> --
>>> 2.1.4
>>>
>>> _______________________________________________
>>> dev mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>> <https://mail.openvswitch.org/mailman/listinfo/ovs-dev>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev