~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/core/ieee8021q_helpers.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 // Copyright (c) 2024 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
  3 
  4 #include <linux/array_size.h>
  5 #include <linux/printk.h>
  6 #include <linux/types.h>
  7 #include <net/dscp.h>
  8 #include <net/ieee8021q.h>
  9 
 10 /* The following arrays map Traffic Types (TT) to traffic classes (TC) for
 11  * different number of queues as shown in the example provided by
 12  * IEEE 802.1Q-2022 in Annex I "I.3 Traffic type to traffic class mapping" and
 13  * Table I-1 "Traffic type to traffic class mapping".
 14  */
 15 static const u8 ieee8021q_8queue_tt_tc_map[] = {
 16         [IEEE8021Q_TT_BK] = 0,
 17         [IEEE8021Q_TT_BE] = 1,
 18         [IEEE8021Q_TT_EE] = 2,
 19         [IEEE8021Q_TT_CA] = 3,
 20         [IEEE8021Q_TT_VI] = 4,
 21         [IEEE8021Q_TT_VO] = 5,
 22         [IEEE8021Q_TT_IC] = 6,
 23         [IEEE8021Q_TT_NC] = 7,
 24 };
 25 
 26 static const u8 ieee8021q_7queue_tt_tc_map[] = {
 27         [IEEE8021Q_TT_BK] = 0,
 28         [IEEE8021Q_TT_BE] = 1,
 29         [IEEE8021Q_TT_EE] = 2,
 30         [IEEE8021Q_TT_CA] = 3,
 31         [IEEE8021Q_TT_VI] = 4,  [IEEE8021Q_TT_VO] = 4,
 32         [IEEE8021Q_TT_IC] = 5,
 33         [IEEE8021Q_TT_NC] = 6,
 34 };
 35 
 36 static const u8 ieee8021q_6queue_tt_tc_map[] = {
 37         [IEEE8021Q_TT_BK] = 0,
 38         [IEEE8021Q_TT_BE] = 1,
 39         [IEEE8021Q_TT_EE] = 2,  [IEEE8021Q_TT_CA] = 2,
 40         [IEEE8021Q_TT_VI] = 3,  [IEEE8021Q_TT_VO] = 3,
 41         [IEEE8021Q_TT_IC] = 4,
 42         [IEEE8021Q_TT_NC] = 5,
 43 };
 44 
 45 static const u8 ieee8021q_5queue_tt_tc_map[] = {
 46         [IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
 47         [IEEE8021Q_TT_EE] = 1, [IEEE8021Q_TT_CA] = 1,
 48         [IEEE8021Q_TT_VI] = 2, [IEEE8021Q_TT_VO] = 2,
 49         [IEEE8021Q_TT_IC] = 3,
 50         [IEEE8021Q_TT_NC] = 4,
 51 };
 52 
 53 static const u8 ieee8021q_4queue_tt_tc_map[] = {
 54         [IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
 55         [IEEE8021Q_TT_EE] = 1, [IEEE8021Q_TT_CA] = 1,
 56         [IEEE8021Q_TT_VI] = 2, [IEEE8021Q_TT_VO] = 2,
 57         [IEEE8021Q_TT_IC] = 3, [IEEE8021Q_TT_NC] = 3,
 58 };
 59 
 60 static const u8 ieee8021q_3queue_tt_tc_map[] = {
 61         [IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
 62         [IEEE8021Q_TT_EE] = 0, [IEEE8021Q_TT_CA] = 0,
 63         [IEEE8021Q_TT_VI] = 1, [IEEE8021Q_TT_VO] = 1,
 64         [IEEE8021Q_TT_IC] = 2, [IEEE8021Q_TT_NC] = 2,
 65 };
 66 
 67 static const u8 ieee8021q_2queue_tt_tc_map[] = {
 68         [IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
 69         [IEEE8021Q_TT_EE] = 0, [IEEE8021Q_TT_CA] = 0,
 70         [IEEE8021Q_TT_VI] = 1, [IEEE8021Q_TT_VO] = 1,
 71         [IEEE8021Q_TT_IC] = 1, [IEEE8021Q_TT_NC] = 1,
 72 };
 73 
 74 static const u8 ieee8021q_1queue_tt_tc_map[] = {
 75         [IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
 76         [IEEE8021Q_TT_EE] = 0, [IEEE8021Q_TT_CA] = 0,
 77         [IEEE8021Q_TT_VI] = 0, [IEEE8021Q_TT_VO] = 0,
 78         [IEEE8021Q_TT_IC] = 0, [IEEE8021Q_TT_NC] = 0,
 79 };
 80 
 81 /**
 82  * ieee8021q_tt_to_tc - Map IEEE 802.1Q Traffic Type to Traffic Class
 83  * @tt: IEEE 802.1Q Traffic Type
 84  * @num_queues: Number of queues
 85  *
 86  * This function maps an IEEE 802.1Q Traffic Type to a Traffic Class (TC) based
 87  * on the number of queues configured on the NIC. The mapping is based on the
 88  * example provided by IEEE 802.1Q-2022 in Annex I "I.3 Traffic type to traffic
 89  * class mapping" and Table I-1 "Traffic type to traffic class mapping".
 90  *
 91  * Return: Traffic Class corresponding to the given Traffic Type or negative
 92  * value in case of error.
 93  */
 94 int ieee8021q_tt_to_tc(enum ieee8021q_traffic_type tt, unsigned int num_queues)
 95 {
 96         if (tt < 0 || tt >= IEEE8021Q_TT_MAX) {
 97                 pr_err("Requested Traffic Type (%d) is out of range (%d)\n", tt,
 98                        IEEE8021Q_TT_MAX);
 99                 return -EINVAL;
100         }
101 
102         switch (num_queues) {
103         case 8:
104                 compiletime_assert(ARRAY_SIZE(ieee8021q_8queue_tt_tc_map) !=
105                                    IEEE8021Q_TT_MAX - 1,
106                                    "ieee8021q_8queue_tt_tc_map != max - 1");
107                 return ieee8021q_8queue_tt_tc_map[tt];
108         case 7:
109                 compiletime_assert(ARRAY_SIZE(ieee8021q_7queue_tt_tc_map) !=
110                                    IEEE8021Q_TT_MAX - 1,
111                                    "ieee8021q_7queue_tt_tc_map != max - 1");
112 
113                 return ieee8021q_7queue_tt_tc_map[tt];
114         case 6:
115                 compiletime_assert(ARRAY_SIZE(ieee8021q_6queue_tt_tc_map) !=
116                                    IEEE8021Q_TT_MAX - 1,
117                                    "ieee8021q_6queue_tt_tc_map != max - 1");
118 
119                 return ieee8021q_6queue_tt_tc_map[tt];
120         case 5:
121                 compiletime_assert(ARRAY_SIZE(ieee8021q_5queue_tt_tc_map) !=
122                                    IEEE8021Q_TT_MAX - 1,
123                                    "ieee8021q_5queue_tt_tc_map != max - 1");
124 
125                 return ieee8021q_5queue_tt_tc_map[tt];
126         case 4:
127                 compiletime_assert(ARRAY_SIZE(ieee8021q_4queue_tt_tc_map) !=
128                                    IEEE8021Q_TT_MAX - 1,
129                                    "ieee8021q_4queue_tt_tc_map != max - 1");
130 
131                 return ieee8021q_4queue_tt_tc_map[tt];
132         case 3:
133                 compiletime_assert(ARRAY_SIZE(ieee8021q_3queue_tt_tc_map) !=
134                                    IEEE8021Q_TT_MAX - 1,
135                                    "ieee8021q_3queue_tt_tc_map != max - 1");
136 
137                 return ieee8021q_3queue_tt_tc_map[tt];
138         case 2:
139                 compiletime_assert(ARRAY_SIZE(ieee8021q_2queue_tt_tc_map) !=
140                                    IEEE8021Q_TT_MAX - 1,
141                                    "ieee8021q_2queue_tt_tc_map != max - 1");
142 
143                 return ieee8021q_2queue_tt_tc_map[tt];
144         case 1:
145                 compiletime_assert(ARRAY_SIZE(ieee8021q_1queue_tt_tc_map) !=
146                                    IEEE8021Q_TT_MAX - 1,
147                                    "ieee8021q_1queue_tt_tc_map != max - 1");
148 
149                 return ieee8021q_1queue_tt_tc_map[tt];
150         }
151 
152         pr_err("Invalid number of queues %d\n", num_queues);
153 
154         return -EINVAL;
155 }
156 EXPORT_SYMBOL_GPL(ieee8021q_tt_to_tc);
157 
158 /**
159  * ietf_dscp_to_ieee8021q_tt - Map IETF DSCP to IEEE 802.1Q Traffic Type
160  * @dscp: IETF DSCP value
161  *
162  * This function maps an IETF DSCP value to an IEEE 802.1Q Traffic Type (TT).
163  * Since there is no corresponding mapping between DSCP and IEEE 802.1Q Traffic
164  * Type, this function is inspired by the RFC8325 documentation which describe
165  * the mapping between DSCP and 802.11 User Priority (UP) values.
166  *
167  * Return: IEEE 802.1Q Traffic Type corresponding to the given DSCP value
168  */
169 int ietf_dscp_to_ieee8021q_tt(u8 dscp)
170 {
171         switch (dscp) {
172         case DSCP_CS0:
173         /* Comment from RFC8325:
174          * [RFC4594], Section 4.8, recommends High-Throughput Data be marked
175          * AF1x (that is, AF11, AF12, and AF13, according to the rules defined
176          * in [RFC2475]).
177          *
178          * By default (as described in Section 2.3), High-Throughput Data will
179          * map to UP 1 and, thus, to the Background Access Category (AC_BK),
180          * which is contrary to the intent expressed in [RFC4594].
181 
182          * Unfortunately, there really is no corresponding fit for the High-
183          * Throughput Data service class within the constrained 4 Access
184          * Category [IEEE.802.11-2016] model.  If the High-Throughput Data
185          * service class is assigned to the Best Effort Access Category (AC_BE),
186          * then it would contend with Low-Latency Data (while [RFC4594]
187          * recommends a distinction in servicing between these service classes)
188          * as well as with the default service class; alternatively, if it is
189          * assigned to the Background Access Category (AC_BK), then it would
190          * receive a less-then-best-effort service and contend with Low-Priority
191          * Data (as discussed in Section 4.2.10).
192          *
193          * As such, since there is no directly corresponding fit for the High-
194          * Throughout Data service class within the [IEEE.802.11-2016] model, it
195          * is generally RECOMMENDED to map High-Throughput Data to UP 0, thereby
196          * admitting it to the Best Effort Access Category (AC_BE).
197          *
198          * Note: The above text is from RFC8325 which is describing the mapping
199          * between DSCP and 802.11 User Priority (UP) values. The mapping
200          * between UP and IEEE 802.1Q Traffic Type is not defined in the RFC but
201          * the 802.11 AC_BK and AC_BE are closely related to the IEEE 802.1Q
202          * Traffic Types BE and BK.
203          */
204         case DSCP_AF11:
205         case DSCP_AF12:
206         case DSCP_AF13:
207                 return IEEE8021Q_TT_BE;
208         /* Comment from RFC8325:
209          * RFC3662 and RFC4594 both recommend Low-Priority Data be marked
210          * with DSCP CS1. The Low-Priority Data service class loosely
211          * corresponds to the [IEEE.802.11-2016] Background Access Category
212          */
213         case DSCP_CS1:
214                 return IEEE8021Q_TT_BK;
215         case DSCP_CS2:
216         case DSCP_AF21:
217         case DSCP_AF22:
218         case DSCP_AF23:
219                 return IEEE8021Q_TT_EE;
220         case DSCP_CS3:
221         case DSCP_AF31:
222         case DSCP_AF32:
223         case DSCP_AF33:
224                 return IEEE8021Q_TT_CA;
225         case DSCP_CS4:
226         case DSCP_AF41:
227         case DSCP_AF42:
228         case DSCP_AF43:
229                 return IEEE8021Q_TT_VI;
230         case DSCP_CS5:
231         case DSCP_EF:
232         case DSCP_VOICE_ADMIT:
233                 return IEEE8021Q_TT_VO;
234         case DSCP_CS6:
235                 return IEEE8021Q_TT_IC;
236         case DSCP_CS7:
237                 return IEEE8021Q_TT_NC;
238         }
239 
240         return SIMPLE_IETF_DSCP_TO_IEEE8021Q_TT(dscp);
241 }
242 EXPORT_SYMBOL_GPL(ietf_dscp_to_ieee8021q_tt);
243 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php