From patchwork Fri Aug 23 19:14:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 1152386 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=herbertland.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=herbertland-com.20150623.gappssmtp.com header.i=@herbertland-com.20150623.gappssmtp.com header.b="tgjWIOn8"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46FWLz5QtCz9s3Z for ; Sat, 24 Aug 2019 05:15:23 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391144AbfHWTPW (ORCPT ); Fri, 23 Aug 2019 15:15:22 -0400 Received: from mail-pg1-f193.google.com ([209.85.215.193]:35416 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389260AbfHWTPW (ORCPT ); Fri, 23 Aug 2019 15:15:22 -0400 Received: by mail-pg1-f193.google.com with SMTP id n4so6281020pgv.2 for ; Fri, 23 Aug 2019 12:15:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=herbertland-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=007gyF4jCeKQJ0bKVeNxm3ngz1HOyBHE6sCB/u+npaQ=; b=tgjWIOn8omWAxqqhAmYslsIBRijzVpvqr685EW+7rjDXIjB4N1UvLGvbz8IWeon0OW TeA8e441ncO45JV1vklvc/1heu1mZCbFCLwPnRn4q4wAEDNEGjloH2A//sIKV5f9DqYy 9hWkMNv8JugMBBiel+P5osXctAENgjzHr0Z7pwAM+8JTWOSjDAKEJ0axpOk1GTZc8HbF PL7yenCdb7LV0CMsA+5lvgtybGUDenP9Bbft2SFcgDPts4EKBp/5cQpwNTb9flTa3F9B wrxDP2YBpbAQ3i3810VJDMlnVa6ke+ZhX5Nqn4P0SXYMos77Qe+b+QndtLFVRFu60Yp0 r3sQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=007gyF4jCeKQJ0bKVeNxm3ngz1HOyBHE6sCB/u+npaQ=; b=MIOs5VvU1eIz+eXgQiFz4trfsMkCThiM5cFqKUbI2Wxzb4mcQ01NXArcDX/hJ9Kb8y i0xKac3283TqmigndluGseN3X4aq9vIGUcGBr9f4a0UqL965OWT2YTHDbueLcrx12YHu o0DaxNaa286iS489jKQNJeOoJpiZWnFJIFeus1bERywqIhXAvtC0ZHbU9KSNztdfXGh6 iJgZXoPDF/k8MOMbDBEvdV4bfXuOMcYIOSwRWbya/F+4dtBOYmNxnyNIfrXr73VRkQIM H0aYs7r73meEkYt7ha8GxyqGDkbzT+voNKL/s8hyzdK+yc+Su76btz7QinVkMYVY2Lr0 TdBg== X-Gm-Message-State: APjAAAUaYlAbT7SgkzLy4ea+ggm0mbxKLYpsh6SF4eohZH1tG44rsFn+ KlDVEWlXIvm35uv1ZiyHPmPasA== X-Google-Smtp-Source: APXvYqwaOIOKs3NrHnR2Ti5ECopMAHvT3iBIQjipFtT9R3RrWSg77taShuGaDyE1gU0t+d/CIX6GOA== X-Received: by 2002:a17:90a:342d:: with SMTP id o42mr6990033pjb.27.1566587720894; Fri, 23 Aug 2019 12:15:20 -0700 (PDT) Received: from localhost.localdomain (c-73-202-182-113.hsd1.ca.comcast.net. [73.202.182.113]) by smtp.gmail.com with ESMTPSA id i6sm3146252pfo.16.2019.08.23.12.15.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 23 Aug 2019 12:15:20 -0700 (PDT) From: Tom Herbert To: davem@davemloft.net, netdev@vger.kernel.org Cc: Tom Herbert , Tom Herbert Subject: [PATCH v4 net-next 5/7] ip6tlvs: Add TX parameters Date: Fri, 23 Aug 2019 12:14:01 -0700 Message-Id: <1566587643-16594-6-git-send-email-tom@herbertland.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1566587643-16594-1-git-send-email-tom@herbertland.com> References: <1566587643-16594-1-git-send-email-tom@herbertland.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Tom Herbert Define a number of transmit parameters for TLV Parameter table definitions. These will be used for validating TLVs that are set on a socket. Signed-off-by: Tom Herbert --- include/net/ipeh.h | 18 ++++++++++++++++ include/uapi/linux/ipeh.h | 8 +++++++ net/ipv6/exthdrs_common.c | 53 +++++++++++++++++++++++++++++++++++++++++++++- net/ipv6/exthdrs_options.c | 45 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 1 deletion(-) diff --git a/include/net/ipeh.h b/include/net/ipeh.h index aaa2910..de6d9d0 100644 --- a/include/net/ipeh.h +++ b/include/net/ipeh.h @@ -20,6 +20,17 @@ struct tlv_rx_params { }; struct tlv_tx_params { + unsigned char admin_perm : 2; + unsigned char user_perm : 2; + unsigned char class : 3; + unsigned char rsvd : 1; + unsigned char align_mult : 4; + unsigned char align_off : 4; + unsigned char data_len_mult : 4; + unsigned char data_len_off : 4; + unsigned char min_data_len; + unsigned char max_data_len; + unsigned short preferred_order; }; struct tlv_params { @@ -54,6 +65,13 @@ struct tlv_param_table { extern struct tlv_param_table ipv6_tlv_param_table; +/* Preferred TLV ordering for HBH and Dest options (placed by increasing order) + */ +#define IPEH_TLV_PREF_ORDER_HAO 10 +#define IPEH_TLV_PREF_ORDER_ROUTERALERT 20 +#define IPEH_TLV_PREF_ORDER_JUMBO 30 +#define IPEH_TLV_PREF_ORDER_CALIPSO 40 + int __ipeh_tlv_set(struct tlv_param_table *tlv_param_table, unsigned char type, const struct tlv_params *params, const struct tlv_ops *ops); diff --git a/include/uapi/linux/ipeh.h b/include/uapi/linux/ipeh.h index c4302b7..dbf0728 100644 --- a/include/uapi/linux/ipeh.h +++ b/include/uapi/linux/ipeh.h @@ -13,4 +13,12 @@ IPEH_TLV_CLASS_FLAG_RTRDSTOPT | \ IPEH_TLV_CLASS_FLAG_DSTOPT) +/* TLV permissions values */ +enum { + IPEH_TLV_PERM_NONE, + IPEH_TLV_PERM_WITH_CHECK, + IPEH_TLV_PERM_NO_CHECK, + IPEH_TLV_PERM_MAX = IPEH_TLV_PERM_NO_CHECK +}; + #endif /* _UAPI_LINUX_IPEH_H */ diff --git a/net/ipv6/exthdrs_common.c b/net/ipv6/exthdrs_common.c index cc8db9e..791f6e4 100644 --- a/net/ipv6/exthdrs_common.c +++ b/net/ipv6/exthdrs_common.c @@ -3,6 +3,7 @@ /* Extension header and TLV library code that is not specific to IPv6. */ #include #include +#include struct ipv6_txoptions * ipeh_dup_options(struct sock *sk, struct ipv6_txoptions *opt) @@ -265,6 +266,13 @@ EXPORT_SYMBOL(ipeh_parse_tlv); /* Default (unset) values for TLV parameters */ static const struct tlv_proc tlv_default_proc = { + .params.t = { + .admin_perm = IPEH_TLV_PERM_NO_CHECK, + .user_perm = IPEH_TLV_PERM_NONE, + .align_mult = (4 - 1), /* Default alignment: 4n + 2 */ + .align_off = 2, + .max_data_len = 255, + }, }; static DEFINE_MUTEX(tlv_mutex); @@ -284,16 +292,45 @@ static void tlv_param_table_release(struct rcu_head *rcu) } /* mutex held */ +static int check_order(struct tlv_param_table_data *tpt, unsigned char type, + unsigned short order) +{ + int i; + + if (!order) + return -EINVAL; + + for (i = 2; i < 256; i++) { + struct tlv_type *ttype = &tpt->types[tpt->entries[i]]; + + if (!tpt->entries[i]) + continue; + + if (order == ttype->proc.params.t.preferred_order && + i != type) + return -EALREADY; + } + + return 0; +} + +/* mutex held */ static int __tlv_set_one(struct tlv_param_table *tlv_param_table, unsigned char type, const struct tlv_params *params, const struct tlv_ops *ops) { struct tlv_param_table_data *tpt, *told; struct tlv_type *ttype; + int retv; told = rcu_dereference_protected(tlv_param_table->data, lockdep_is_held(&tlv_mutex)); + /* Check preferred order */ + retv = check_order(told, type, params->t.preferred_order); + if (retv) + return retv; + /* Create new TLV table. If there is no exsiting entry then we are * adding a new one to the table, else we're modifying an entry. */ @@ -422,7 +459,7 @@ int ipeh_exthdrs_init(struct tlv_param_table *tlv_param_table, int num_init_params) { struct tlv_param_table_data *tpt; - int pos = 0, i; + int pos = 0, i, j; size_t tsize; tsize = tlv_param_table_size(num_init_params + 1); @@ -448,6 +485,20 @@ int ipeh_exthdrs_init(struct tlv_param_table *tlv_param_table, goto err_inval; } + if (WARN_ON(!tpi->proc.params.t.preferred_order)) { + /* Preferred order must be non-zero */ + goto err_inval; + } + + for (j = 0; j < i; j++) { + const struct tlv_proc_init *tpix = &tlv_init_params[j]; + + if (WARN_ON(tpi->proc.params.t.preferred_order == + tpix->proc.params.t.preferred_order)) { + /* Preferred order must be unique */ + goto err_inval; + } + } tpt->types[pos].proc = tpi->proc; tpt->entries[tpi->type] = pos; } diff --git a/net/ipv6/exthdrs_options.c b/net/ipv6/exthdrs_options.c index d4b373e..3b50b58 100644 --- a/net/ipv6/exthdrs_options.c +++ b/net/ipv6/exthdrs_options.c @@ -183,6 +183,17 @@ static const struct tlv_proc_init tlv_ipv6_init_params[] __initconst = { .proc.ops.func = ipv6_dest_hao, .proc.params.r.class = IPEH_TLV_CLASS_FLAG_DSTOPT, + + .proc.params.t = { + .preferred_order = IPEH_TLV_PREF_ORDER_HAO, + .admin_perm = IPEH_TLV_PERM_NO_CHECK, + .user_perm = IPEH_TLV_PERM_NONE, + .class = IPEH_TLV_CLASS_FLAG_DSTOPT, + .align_mult = (8 - 1), /* Align to 8n + 6 */ + .align_off = 6, + .min_data_len = 16, + .max_data_len = 16, + }, }, #endif { @@ -190,18 +201,52 @@ static const struct tlv_proc_init tlv_ipv6_init_params[] __initconst = { .proc.ops.func = ipv6_hop_ra, .proc.params.r.class = IPEH_TLV_CLASS_FLAG_HOPOPT, + + .proc.params.t = { + .preferred_order = IPEH_TLV_PREF_ORDER_ROUTERALERT, + .admin_perm = IPEH_TLV_PERM_NO_CHECK, + .user_perm = IPEH_TLV_PERM_NONE, + .class = IPEH_TLV_CLASS_FLAG_HOPOPT, + .align_mult = (2 - 1), /* Align to 2n */ + .min_data_len = 2, + .max_data_len = 2, + }, }, { .type = IPV6_TLV_JUMBO, .proc.ops.func = ipv6_hop_jumbo, .proc.params.r.class = IPEH_TLV_CLASS_FLAG_HOPOPT, + + .proc.params.t = { + .preferred_order = IPEH_TLV_PREF_ORDER_JUMBO, + .admin_perm = IPEH_TLV_PERM_NO_CHECK, + .user_perm = IPEH_TLV_PERM_NONE, + .class = IPEH_TLV_CLASS_FLAG_HOPOPT, + .align_mult = (4 - 1), /* Align to 4n + 2 */ + .align_off = 2, + .min_data_len = 4, + .max_data_len = 4, + }, }, { .type = IPV6_TLV_CALIPSO, .proc.ops.func = ipv6_hop_calipso, .proc.params.r.class = IPEH_TLV_CLASS_FLAG_HOPOPT, + + .proc.params.t = { + .preferred_order = IPEH_TLV_PREF_ORDER_CALIPSO, + .admin_perm = IPEH_TLV_PERM_NO_CHECK, + .user_perm = IPEH_TLV_PERM_NONE, + .class = IPEH_TLV_CLASS_FLAG_HOPOPT, + .align_mult = (4 - 1), /* Align to 4n + 2 */ + .align_off = 2, + .min_data_len = 8, + .max_data_len = 252, + .data_len_mult = (4 - 1), + /* Length is multiple of 4 */ + }, }, };