From patchwork Mon Apr 15 17:52:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 1085855 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="VYgLlh18"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jbgx3tTqz9s71 for ; Tue, 16 Apr 2019 03:53:01 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727796AbfDORxA (ORCPT ); Mon, 15 Apr 2019 13:53:00 -0400 Received: from mail-pg1-f196.google.com ([209.85.215.196]:34109 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727691AbfDORw6 (ORCPT ); Mon, 15 Apr 2019 13:52:58 -0400 Received: by mail-pg1-f196.google.com with SMTP id v12so8958004pgq.1 for ; Mon, 15 Apr 2019 10:52:58 -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=KhQ84OjfFlyfUwhWf9s/hx3t2v0v8hYe7M26CMclbAY=; b=VYgLlh184/Bf9zjKAiGncCVuC3k3kSNoXoav6H7m6aoVtpY36dOVL5NqiP3NalIhTA dN6mCnnFiLXZlpAlwXdGBOLUua1VuP59pRVt0+NHTy7xqtmlifn2XvfWOWcb8soKhERk Addttz1ixHQX6h1NSpV/kB5hNX1y10yo4kmD9Zne3xYlIS01HYcLAlqi9HFlAs7g2Tyr wpTRKjPTK0DDaXAmc/rzv5C9+8wxeaGxLI42TjG4ChKoH2vHY8negIEDVpxuS+zk/Quy riBwrgpsX5Jc2KY02TBySHFG+SHolmV2NiVAmJBCW0zzG9C47TfC+HuBnovy0e1UT1qj hpdg== 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=KhQ84OjfFlyfUwhWf9s/hx3t2v0v8hYe7M26CMclbAY=; b=BR3dkqvF0ugCHxi6O+OKBdVn971YF0L/3xVLxijEMyJAvytTVVQMve2cQ1SLl+VAut J9cPFTWomtbJJ1RdKGUHiA9+lRNVOvo/bLOB66dGTtLD6NxfMGpNEku9+I2bmbeDD2ZN Q1UW2V8k4WQ5KEnLxQbuAtXzsHeDd+pPcAw6qYTvuldc3laYjxNuuScM3wQ/tbW4p8dz 09Wuh+sxiozBBcQGs1fCUyqOsNFnZC7Rv8UnUedJtOFohAvEVLnMda6zB3/DnGZ56ng2 bWgwbAaKA39U3/4yKwJUDHElAeYvNdZ2bRHA36PYbs3dmYccVcXrit7YPFfGkHjPZO0Q REEA== X-Gm-Message-State: APjAAAUSyOqG1RdLOamRB6dnJgtESlGyZIPL/gkn0swSQJnnp4jKDs/F k/BIkIZ79g2zYxycq3OCQG2f+A== X-Google-Smtp-Source: APXvYqzol+oh/lcydSvmsj6/cg0LD437RbqqXac3vFykJSnJKe567CcoxmzBd03AxIf54sQGytNHtQ== X-Received: by 2002:a63:7843:: with SMTP id t64mr53223940pgc.130.1555350777758; Mon, 15 Apr 2019 10:52:57 -0700 (PDT) Received: from localhost.localdomain (c-73-223-249-119.hsd1.ca.comcast.net. [73.223.249.119]) by smtp.gmail.com with ESMTPSA id t24sm58751170pfe.110.2019.04.15.10.52.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 15 Apr 2019 10:52:57 -0700 (PDT) From: Tom Herbert X-Google-Original-From: Tom Herbert To: davem@davemloft.net, netdev@vger.kernel.org Cc: Tom Herbert Subject: [PATCH v3 net-next 5/7] exthdrs: Add TX parameters Date: Mon, 15 Apr 2019 10:52:18 -0700 Message-Id: <1555350740-23490-6-git-send-email-tom@quantonium.net> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1555350740-23490-1-git-send-email-tom@quantonium.net> References: <1555350740-23490-1-git-send-email-tom@quantonium.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Define a number of transmit parameters for TLV Parameter table definitions. These will be used for validating TLVs that are set on a socket. --- include/net/ipv6.h | 26 ++++++++++++++++++++- include/uapi/linux/in6.h | 8 +++++++ net/ipv6/exthdrs.c | 2 +- net/ipv6/exthdrs_core.c | 22 +++++++++++++++++- net/ipv6/exthdrs_options.c | 57 ++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 108 insertions(+), 7 deletions(-) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 41da032..9b25d08 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -390,8 +390,26 @@ struct tlv_ops { bool (*func)(unsigned int class, struct sk_buff *skb, int offset); }; +struct tlv_rx_params { + unsigned char class : 3; +}; + +struct tlv_tx_params { + unsigned char admin_perm : 2; + unsigned char user_perm : 2; + unsigned char class : 3; + 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 char preferred_order; +}; + struct tlv_params { - unsigned char rx_class : 3; + struct tlv_rx_params r; + struct tlv_tx_params t; }; struct tlv_proc { @@ -417,6 +435,12 @@ struct tlv_param_table { extern struct tlv_param_table ipv6_tlv_param_table; +/* Preferred TLV ordering (placed by increasing order) */ +#define TLV_PREF_ORDER_HAO 10 +#define TLV_PREF_ORDER_ROUTERALERT 20 +#define TLV_PREF_ORDER_JUMBO 30 +#define TLV_PREF_ORDER_CALIPSO 40 + int tlv_set_proc(struct tlv_param_table *tlv_param_table, unsigned char type, const struct tlv_proc *proc); int tlv_unset_proc(struct tlv_param_table *tlv_param_table, unsigned char type); diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h index 8b9ac7f..6a99ee1 100644 --- a/include/uapi/linux/in6.h +++ b/include/uapi/linux/in6.h @@ -307,4 +307,12 @@ struct in6_flowlabel_req { #define IPV6_TLV_CLASS_ANY_DSTOPT (IPV6_TLV_CLASS_FLAG_RTRDSTOPT | \ IPV6_TLV_CLASS_FLAG_DSTOPT) +/* TLV permissions values */ +enum { + IPV6_TLV_PERM_NONE, + IPV6_TLV_PERM_WITH_CHECK, + IPV6_TLV_PERM_NO_CHECK, + IPV6_TLV_PERM_MAX = IPV6_TLV_PERM_NO_CHECK +}; + #endif /* _UAPI_LINUX_IN6_H */ diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index b28c108..520c2eb 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -166,7 +166,7 @@ static bool ip6_parse_tlv(unsigned int class, struct sk_buff *skb, goto bad; curr = tlv_get_proc(&ipv6_tlv_param_table, nh[off]); - if ((curr->params.rx_class & class) && curr->ops.func) { + if ((curr->params.r.class & class) && curr->ops.func) { /* Handler will apply additional checks to * the TLV */ diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c index def52b5..53e92fd 100644 --- a/net/ipv6/exthdrs_core.c +++ b/net/ipv6/exthdrs_core.c @@ -431,7 +431,18 @@ static void tlv_param_table_release(struct rcu_head *rcu) /* Default (unset) values for TLV parameters */ static const struct tlv_proc tlv_default_proc = { - .params.rx_class = 0, + .params.r.class = 0, + + .params.t.preferred_order = 0, + .params.t.admin_perm = IPV6_TLV_PERM_NO_CHECK, + .params.t.user_perm = IPV6_TLV_PERM_NONE, + .params.t.class = 0, + .params.t.align_mult = (4 - 1), /* Default alignment: 4n + 2 */ + .params.t.align_off = 2, + .params.t.min_data_len = 0, + .params.t.max_data_len = 255, + .params.t.data_len_mult = (1 - 1), /* No default length align */ + .params.t.data_len_off = 0, }; static size_t tlv_param_table_size(unsigned char count) @@ -650,10 +661,13 @@ int exthdrs_init(struct tlv_param_table *tlv_param_table, const struct tlv_proc_init *tlv_init_params, int num_init_params) { + unsigned long check_map[BITS_TO_LONGS(256)]; struct tlv_param_table_data *tpt; size_t tsize; int i; + memset(check_map, 0, sizeof(check_map)); + tsize = tlv_param_table_size(num_init_params + 1); tpt = kvmalloc(tsize, GFP_KERNEL); @@ -667,6 +681,7 @@ int exthdrs_init(struct tlv_param_table *tlv_param_table, for (i = 0; i < num_init_params; i++) { const struct tlv_proc_init *tpi = &tlv_init_params[i]; + unsigned int order = tpi->proc.params.t.preferred_order; struct tlv_proc *tp = &tpt->procs[i + 1]; if (WARN_ON(tpi->type < 2)) { @@ -680,6 +695,11 @@ int exthdrs_init(struct tlv_param_table *tlv_param_table, return -EINVAL; } + if (order) { + WARN_ON(test_bit(order, check_map)); + set_bit(order, check_map); + } + *tp = tpi->proc; tpt->entries[tpi->type] = i + 1; } diff --git a/net/ipv6/exthdrs_options.c b/net/ipv6/exthdrs_options.c index 02d12c5..042ca14 100644 --- a/net/ipv6/exthdrs_options.c +++ b/net/ipv6/exthdrs_options.c @@ -181,26 +181,75 @@ static const struct tlv_proc_init tlv_init_params[] __initconst = { .type = IPV6_TLV_HAO, .proc.ops.func = ipv6_dest_hao, - .proc.params.rx_class = IPV6_TLV_CLASS_FLAG_DSTOPT, + + .proc.params.r.class = IPV6_TLV_CLASS_FLAG_DSTOPT, + + .proc.params.t.preferred_order = TLV_PREF_ORDER_HAO, + .proc.params.t.admin_perm = IPV6_TLV_PERM_NO_CHECK, + .proc.params.t.user_perm = IPV6_TLV_PERM_NONE, + .proc.params.t.class = IPV6_TLV_CLASS_FLAG_DSTOPT, + .proc.params.t.align_mult = (8 - 1), /* Align to 8n + 6 */ + .proc.params.t.align_off = 6, + .proc.params.t.min_data_len = 16, + .proc.params.t.max_data_len = 16, + .proc.params.t.data_len_mult = (1 - 1), /* Fixed length */ + .proc.params.t.data_len_off = 0, }, #endif { .type = IPV6_TLV_ROUTERALERT, .proc.ops.func = ipv6_hop_ra, - .proc.params.rx_class = IPV6_TLV_CLASS_FLAG_HOPOPT, + + .proc.params.r.class = IPV6_TLV_CLASS_FLAG_HOPOPT, + + .proc.params.t.preferred_order = TLV_PREF_ORDER_ROUTERALERT, + .proc.params.t.admin_perm = IPV6_TLV_PERM_NO_CHECK, + .proc.params.t.user_perm = IPV6_TLV_PERM_NONE, + .proc.params.t.class = IPV6_TLV_CLASS_FLAG_HOPOPT, + .proc.params.t.align_mult = (2 - 1), /* Align to 2n */ + .proc.params.t.align_off = 0, + .proc.params.t.min_data_len = 2, + .proc.params.t.max_data_len = 2, + .proc.params.t.data_len_mult = (1 - 1), /* Fixed length */ + .proc.params.t.data_len_off = 0, + }, { .type = IPV6_TLV_JUMBO, .proc.ops.func = ipv6_hop_jumbo, - .proc.params.rx_class = IPV6_TLV_CLASS_FLAG_HOPOPT, + + .proc.params.r.class = IPV6_TLV_CLASS_FLAG_HOPOPT, + + .proc.params.t.preferred_order = TLV_PREF_ORDER_JUMBO, + .proc.params.t.admin_perm = IPV6_TLV_PERM_NO_CHECK, + .proc.params.t.user_perm = IPV6_TLV_PERM_NONE, + .proc.params.t.class = IPV6_TLV_CLASS_FLAG_HOPOPT, + .proc.params.t.align_mult = (4 - 1), /* Align to 4n + 2 */ + .proc.params.t.align_off = 2, + .proc.params.t.min_data_len = 4, + .proc.params.t.max_data_len = 4, + .proc.params.t.data_len_mult = (1 - 1), /* Fixed length */ + .proc.params.t.data_len_off = 0, }, { .type = IPV6_TLV_CALIPSO, .proc.ops.func = ipv6_hop_calipso, - .proc.params.rx_class = IPV6_TLV_CLASS_FLAG_HOPOPT, + .proc.params.r.class = IPV6_TLV_CLASS_FLAG_HOPOPT, + + .proc.params.t.preferred_order = TLV_PREF_ORDER_CALIPSO, + .proc.params.t.admin_perm = IPV6_TLV_PERM_NO_CHECK, + .proc.params.t.user_perm = IPV6_TLV_PERM_NONE, + .proc.params.t.class = IPV6_TLV_CLASS_FLAG_HOPOPT, + .proc.params.t.align_mult = (4 - 1), /* Align to 4n + 2 */ + .proc.params.t.align_off = 2, + .proc.params.t.min_data_len = 8, + .proc.params.t.max_data_len = 252, + .proc.params.t.data_len_mult = (4 - 1), + /* Length is multiple of 4 */ + .proc.params.t.data_len_off = 0, }, };