0001
0002 #ifndef MPLS_INTERNAL_H
0003 #define MPLS_INTERNAL_H
0004 #include <net/mpls.h>
0005
0006
0007
0008
0009 #define MAX_NEW_LABELS 30
0010
0011 struct mpls_entry_decoded {
0012 u32 label;
0013 u8 ttl;
0014 u8 tc;
0015 u8 bos;
0016 };
0017
0018 struct mpls_pcpu_stats {
0019 struct mpls_link_stats stats;
0020 struct u64_stats_sync syncp;
0021 };
0022
0023 struct mpls_dev {
0024 int input_enabled;
0025 struct net_device *dev;
0026 struct mpls_pcpu_stats __percpu *stats;
0027
0028 struct ctl_table_header *sysctl;
0029 struct rcu_head rcu;
0030 };
0031
0032 #if BITS_PER_LONG == 32
0033
0034 #define MPLS_INC_STATS_LEN(mdev, len, pkts_field, bytes_field) \
0035 do { \
0036 __typeof__(*(mdev)->stats) *ptr = \
0037 raw_cpu_ptr((mdev)->stats); \
0038 local_bh_disable(); \
0039 u64_stats_update_begin(&ptr->syncp); \
0040 ptr->stats.pkts_field++; \
0041 ptr->stats.bytes_field += (len); \
0042 u64_stats_update_end(&ptr->syncp); \
0043 local_bh_enable(); \
0044 } while (0)
0045
0046 #define MPLS_INC_STATS(mdev, field) \
0047 do { \
0048 __typeof__(*(mdev)->stats) *ptr = \
0049 raw_cpu_ptr((mdev)->stats); \
0050 local_bh_disable(); \
0051 u64_stats_update_begin(&ptr->syncp); \
0052 ptr->stats.field++; \
0053 u64_stats_update_end(&ptr->syncp); \
0054 local_bh_enable(); \
0055 } while (0)
0056
0057 #else
0058
0059 #define MPLS_INC_STATS_LEN(mdev, len, pkts_field, bytes_field) \
0060 do { \
0061 this_cpu_inc((mdev)->stats->stats.pkts_field); \
0062 this_cpu_add((mdev)->stats->stats.bytes_field, (len)); \
0063 } while (0)
0064
0065 #define MPLS_INC_STATS(mdev, field) \
0066 this_cpu_inc((mdev)->stats->stats.field)
0067
0068 #endif
0069
0070 struct sk_buff;
0071
0072 #define LABEL_NOT_SPECIFIED (1 << 20)
0073
0074
0075 #define VIA_ALEN_ALIGN sizeof(unsigned long)
0076 #define MAX_VIA_ALEN (ALIGN(MAX_ADDR_LEN, VIA_ALEN_ALIGN))
0077
0078 enum mpls_payload_type {
0079 MPT_UNSPEC,
0080 MPT_IPV4 = 4,
0081 MPT_IPV6 = 6,
0082
0083
0084
0085
0086
0087 };
0088
0089 struct mpls_nh {
0090 struct net_device *nh_dev;
0091
0092
0093
0094
0095 unsigned int nh_flags;
0096 u8 nh_labels;
0097 u8 nh_via_alen;
0098 u8 nh_via_table;
0099 u8 nh_reserved1;
0100
0101 u32 nh_label[];
0102 };
0103
0104
0105 #define MPLS_NH_VIA_OFF(num_labels) \
0106 ALIGN(sizeof(struct mpls_nh) + (num_labels) * sizeof(u32), \
0107 VIA_ALEN_ALIGN)
0108
0109
0110
0111
0112 #define MPLS_NH_SIZE(num_labels, max_via_alen) \
0113 (MPLS_NH_VIA_OFF((num_labels)) + \
0114 ALIGN((max_via_alen), VIA_ALEN_ALIGN))
0115
0116 enum mpls_ttl_propagation {
0117 MPLS_TTL_PROP_DEFAULT,
0118 MPLS_TTL_PROP_ENABLED,
0119 MPLS_TTL_PROP_DISABLED,
0120 };
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 struct mpls_route {
0144 struct rcu_head rt_rcu;
0145 u8 rt_protocol;
0146 u8 rt_payload_type;
0147 u8 rt_max_alen;
0148 u8 rt_ttl_propagate;
0149 u8 rt_nhn;
0150
0151
0152
0153 u8 rt_nhn_alive;
0154 u8 rt_nh_size;
0155 u8 rt_via_offset;
0156 u8 rt_reserved1;
0157 struct mpls_nh rt_nh[];
0158 };
0159
0160 #define for_nexthops(rt) { \
0161 int nhsel; const struct mpls_nh *nh; \
0162 for (nhsel = 0, nh = (rt)->rt_nh; \
0163 nhsel < (rt)->rt_nhn; \
0164 nh = (void *)nh + (rt)->rt_nh_size, nhsel++)
0165
0166 #define change_nexthops(rt) { \
0167 int nhsel; struct mpls_nh *nh; \
0168 for (nhsel = 0, nh = (rt)->rt_nh; \
0169 nhsel < (rt)->rt_nhn; \
0170 nh = (void *)nh + (rt)->rt_nh_size, nhsel++)
0171
0172 #define endfor_nexthops(rt) }
0173
0174 static inline struct mpls_entry_decoded mpls_entry_decode(struct mpls_shim_hdr *hdr)
0175 {
0176 struct mpls_entry_decoded result;
0177 unsigned entry = be32_to_cpu(hdr->label_stack_entry);
0178
0179 result.label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT;
0180 result.ttl = (entry & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT;
0181 result.tc = (entry & MPLS_LS_TC_MASK) >> MPLS_LS_TC_SHIFT;
0182 result.bos = (entry & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT;
0183
0184 return result;
0185 }
0186
0187 static inline struct mpls_dev *mpls_dev_get(const struct net_device *dev)
0188 {
0189 return rcu_dereference_rtnl(dev->mpls_ptr);
0190 }
0191
0192 int nla_put_labels(struct sk_buff *skb, int attrtype, u8 labels,
0193 const u32 label[]);
0194 int nla_get_labels(const struct nlattr *nla, u8 max_labels, u8 *labels,
0195 u32 label[], struct netlink_ext_ack *extack);
0196 bool mpls_output_possible(const struct net_device *dev);
0197 unsigned int mpls_dev_mtu(const struct net_device *dev);
0198 bool mpls_pkt_too_big(const struct sk_buff *skb, unsigned int mtu);
0199 void mpls_stats_inc_outucastpkts(struct net_device *dev,
0200 const struct sk_buff *skb);
0201
0202 #endif