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

TOMOYO Linux Cross Reference
Linux/net/mpls/internal.h

Version: ~ [ linux-5.12-rc1 ] ~ [ linux-5.11.2 ] ~ [ linux-5.10.19 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.101 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.177 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.222 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.258 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.258 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ 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.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 #ifndef MPLS_INTERNAL_H
  3 #define MPLS_INTERNAL_H
  4 #include <net/mpls.h>
  5 
  6 /* put a reasonable limit on the number of labels
  7  * we will accept from userspace
  8  */
  9 #define MAX_NEW_LABELS 30
 10 
 11 struct mpls_entry_decoded {
 12         u32 label;
 13         u8 ttl;
 14         u8 tc;
 15         u8 bos;
 16 };
 17 
 18 struct mpls_pcpu_stats {
 19         struct mpls_link_stats  stats;
 20         struct u64_stats_sync   syncp;
 21 };
 22 
 23 struct mpls_dev {
 24         int                             input_enabled;
 25         struct net_device               *dev;
 26         struct mpls_pcpu_stats __percpu *stats;
 27 
 28         struct ctl_table_header         *sysctl;
 29         struct rcu_head                 rcu;
 30 };
 31 
 32 #if BITS_PER_LONG == 32
 33 
 34 #define MPLS_INC_STATS_LEN(mdev, len, pkts_field, bytes_field)          \
 35         do {                                                            \
 36                 __typeof__(*(mdev)->stats) *ptr =                       \
 37                         raw_cpu_ptr((mdev)->stats);                     \
 38                 local_bh_disable();                                     \
 39                 u64_stats_update_begin(&ptr->syncp);                    \
 40                 ptr->stats.pkts_field++;                                \
 41                 ptr->stats.bytes_field += (len);                        \
 42                 u64_stats_update_end(&ptr->syncp);                      \
 43                 local_bh_enable();                                      \
 44         } while (0)
 45 
 46 #define MPLS_INC_STATS(mdev, field)                                     \
 47         do {                                                            \
 48                 __typeof__(*(mdev)->stats) *ptr =                       \
 49                         raw_cpu_ptr((mdev)->stats);                     \
 50                 local_bh_disable();                                     \
 51                 u64_stats_update_begin(&ptr->syncp);                    \
 52                 ptr->stats.field++;                                     \
 53                 u64_stats_update_end(&ptr->syncp);                      \
 54                 local_bh_enable();                                      \
 55         } while (0)
 56 
 57 #else
 58 
 59 #define MPLS_INC_STATS_LEN(mdev, len, pkts_field, bytes_field)          \
 60         do {                                                            \
 61                 this_cpu_inc((mdev)->stats->stats.pkts_field);          \
 62                 this_cpu_add((mdev)->stats->stats.bytes_field, (len));  \
 63         } while (0)
 64 
 65 #define MPLS_INC_STATS(mdev, field)                     \
 66         this_cpu_inc((mdev)->stats->stats.field)
 67 
 68 #endif
 69 
 70 struct sk_buff;
 71 
 72 #define LABEL_NOT_SPECIFIED (1 << 20)
 73 
 74 /* This maximum ha length copied from the definition of struct neighbour */
 75 #define VIA_ALEN_ALIGN sizeof(unsigned long)
 76 #define MAX_VIA_ALEN (ALIGN(MAX_ADDR_LEN, VIA_ALEN_ALIGN))
 77 
 78 enum mpls_payload_type {
 79         MPT_UNSPEC, /* IPv4 or IPv6 */
 80         MPT_IPV4 = 4,
 81         MPT_IPV6 = 6,
 82 
 83         /* Other types not implemented:
 84          *  - Pseudo-wire with or without control word (RFC4385)
 85          *  - GAL (RFC5586)
 86          */
 87 };
 88 
 89 struct mpls_nh { /* next hop label forwarding entry */
 90         struct net_device __rcu *nh_dev;
 91 
 92         /* nh_flags is accessed under RCU in the packet path; it is
 93          * modified handling netdev events with rtnl lock held
 94          */
 95         unsigned int            nh_flags;
 96         u8                      nh_labels;
 97         u8                      nh_via_alen;
 98         u8                      nh_via_table;
 99         u8                      nh_reserved1;
100 
101         u32                     nh_label[0];
102 };
103 
104 /* offset of via from beginning of mpls_nh */
105 #define MPLS_NH_VIA_OFF(num_labels) \
106                 ALIGN(sizeof(struct mpls_nh) + (num_labels) * sizeof(u32), \
107                       VIA_ALEN_ALIGN)
108 
109 /* all nexthops within a route have the same size based on the
110  * max number of labels and max via length across all nexthops
111  */
112 #define MPLS_NH_SIZE(num_labels, max_via_alen)          \
113                 (MPLS_NH_VIA_OFF((num_labels)) +        \
114                 ALIGN((max_via_alen), VIA_ALEN_ALIGN))
115 
116 enum mpls_ttl_propagation {
117         MPLS_TTL_PROP_DEFAULT,
118         MPLS_TTL_PROP_ENABLED,
119         MPLS_TTL_PROP_DISABLED,
120 };
121 
122 /* The route, nexthops and vias are stored together in the same memory
123  * block:
124  *
125  * +----------------------+
126  * | mpls_route           |
127  * +----------------------+
128  * | mpls_nh 0            |
129  * +----------------------+
130  * | alignment padding    |   4 bytes for odd number of labels
131  * +----------------------+
132  * | via[rt_max_alen] 0   |
133  * +----------------------+
134  * | alignment padding    |   via's aligned on sizeof(unsigned long)
135  * +----------------------+
136  * | ...                  |
137  * +----------------------+
138  * | mpls_nh n-1          |
139  * +----------------------+
140  * | via[rt_max_alen] n-1 |
141  * +----------------------+
142  */
143 struct mpls_route { /* next hop label forwarding entry */
144         struct rcu_head         rt_rcu;
145         u8                      rt_protocol;
146         u8                      rt_payload_type;
147         u8                      rt_max_alen;
148         u8                      rt_ttl_propagate;
149         u8                      rt_nhn;
150         /* rt_nhn_alive is accessed under RCU in the packet path; it
151          * is modified handling netdev events with rtnl lock held
152          */
153         u8                      rt_nhn_alive;
154         u8                      rt_nh_size;
155         u8                      rt_via_offset;
156         u8                      rt_reserved1;
157         struct mpls_nh          rt_nh[0];
158 };
159 
160 #define for_nexthops(rt) {                                              \
161         int nhsel; struct mpls_nh *nh;  u8 *__nh;                       \
162         for (nhsel = 0, nh = (rt)->rt_nh, __nh = (u8 *)((rt)->rt_nh);   \
163              nhsel < (rt)->rt_nhn;                                      \
164              __nh += rt->rt_nh_size, nh = (struct mpls_nh *)__nh, nhsel++)
165 
166 #define change_nexthops(rt) {                                           \
167         int nhsel; struct mpls_nh *nh; u8 *__nh;                        \
168         for (nhsel = 0, nh = (struct mpls_nh *)((rt)->rt_nh),           \
169                         __nh = (u8 *)((rt)->rt_nh);                     \
170              nhsel < (rt)->rt_nhn;                                      \
171              __nh += rt->rt_nh_size, nh = (struct mpls_nh *)__nh, nhsel++)
172 
173 #define endfor_nexthops(rt) }
174 
175 static inline struct mpls_shim_hdr mpls_entry_encode(u32 label, unsigned ttl, unsigned tc, bool bos)
176 {
177         struct mpls_shim_hdr result;
178         result.label_stack_entry =
179                 cpu_to_be32((label << MPLS_LS_LABEL_SHIFT) |
180                             (tc << MPLS_LS_TC_SHIFT) |
181                             (bos ? (1 << MPLS_LS_S_SHIFT) : 0) |
182                             (ttl << MPLS_LS_TTL_SHIFT));
183         return result;
184 }
185 
186 static inline struct mpls_entry_decoded mpls_entry_decode(struct mpls_shim_hdr *hdr)
187 {
188         struct mpls_entry_decoded result;
189         unsigned entry = be32_to_cpu(hdr->label_stack_entry);
190 
191         result.label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT;
192         result.ttl = (entry & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT;
193         result.tc =  (entry & MPLS_LS_TC_MASK) >> MPLS_LS_TC_SHIFT;
194         result.bos = (entry & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT;
195 
196         return result;
197 }
198 
199 static inline struct mpls_dev *mpls_dev_get(const struct net_device *dev)
200 {
201         return rcu_dereference_rtnl(dev->mpls_ptr);
202 }
203 
204 int nla_put_labels(struct sk_buff *skb, int attrtype,  u8 labels,
205                    const u32 label[]);
206 int nla_get_labels(const struct nlattr *nla, u8 max_labels, u8 *labels,
207                    u32 label[], struct netlink_ext_ack *extack);
208 bool mpls_output_possible(const struct net_device *dev);
209 unsigned int mpls_dev_mtu(const struct net_device *dev);
210 bool mpls_pkt_too_big(const struct sk_buff *skb, unsigned int mtu);
211 void mpls_stats_inc_outucastpkts(struct net_device *dev,
212                                  const struct sk_buff *skb);
213 
214 #endif /* MPLS_INTERNAL_H */
215 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp