2015-03-03 19:10:47 -06:00
# ifndef MPLS_INTERNAL_H
# define MPLS_INTERNAL_H
struct mpls_shim_hdr {
__be32 label_stack_entry ;
} ;
struct mpls_entry_decoded {
u32 label ;
u8 ttl ;
u8 tc ;
u8 bos ;
} ;
2015-04-22 11:14:37 +01:00
struct mpls_dev {
2015-04-22 11:14:38 +01:00
int input_enabled ;
struct ctl_table_header * sysctl ;
2015-06-05 18:54:45 +01:00
struct rcu_head rcu ;
2015-04-22 11:14:37 +01:00
} ;
2015-03-03 19:10:47 -06:00
struct sk_buff ;
2015-10-23 06:03:27 -07:00
# define LABEL_NOT_SPECIFIED (1 << 20)
# define MAX_NEW_LABELS 2
/* This maximum ha length copied from the definition of struct neighbour */
2015-10-27 00:37:36 +00:00
# define VIA_ALEN_ALIGN sizeof(unsigned long)
# define MAX_VIA_ALEN (ALIGN(MAX_ADDR_LEN, VIA_ALEN_ALIGN))
2015-10-23 06:03:27 -07:00
enum mpls_payload_type {
MPT_UNSPEC , /* IPv4 or IPv6 */
MPT_IPV4 = 4 ,
MPT_IPV6 = 6 ,
/* Other types not implemented:
* - Pseudo - wire with or without control word ( RFC4385 )
* - GAL ( RFC5586 )
*/
} ;
struct mpls_nh { /* next hop label forwarding entry */
struct net_device __rcu * nh_dev ;
2015-12-01 22:18:11 -08:00
unsigned int nh_flags ;
2015-10-23 06:03:27 -07:00
u32 nh_label [ MAX_NEW_LABELS ] ;
u8 nh_labels ;
u8 nh_via_alen ;
u8 nh_via_table ;
} ;
2015-10-27 00:37:36 +00:00
/* The route, nexthops and vias are stored together in the same memory
* block :
*
* + - - - - - - - - - - - - - - - - - - - - - - +
* | mpls_route |
* + - - - - - - - - - - - - - - - - - - - - - - +
* | mpls_nh 0 |
* + - - - - - - - - - - - - - - - - - - - - - - +
* | . . . |
* + - - - - - - - - - - - - - - - - - - - - - - +
* | mpls_nh n - 1 |
* + - - - - - - - - - - - - - - - - - - - - - - +
* | alignment padding |
* + - - - - - - - - - - - - - - - - - - - - - - +
* | via [ rt_max_alen ] 0 |
* + - - - - - - - - - - - - - - - - - - - - - - +
* | . . . |
* + - - - - - - - - - - - - - - - - - - - - - - +
* | via [ rt_max_alen ] n - 1 |
* + - - - - - - - - - - - - - - - - - - - - - - +
*/
2015-10-23 06:03:27 -07:00
struct mpls_route { /* next hop label forwarding entry */
struct rcu_head rt_rcu ;
u8 rt_protocol ;
u8 rt_payload_type ;
2015-10-27 00:37:36 +00:00
u8 rt_max_alen ;
unsigned int rt_nhn ;
2015-12-01 22:18:11 -08:00
unsigned int rt_nhn_alive ;
2015-10-23 06:03:27 -07:00
struct mpls_nh rt_nh [ 0 ] ;
} ;
# define for_nexthops(rt) { \
int nhsel ; struct mpls_nh * nh ; \
for ( nhsel = 0 , nh = ( rt ) - > rt_nh ; \
nhsel < ( rt ) - > rt_nhn ; \
nh + + , nhsel + + )
# define change_nexthops(rt) { \
int nhsel ; struct mpls_nh * nh ; \
for ( nhsel = 0 , nh = ( struct mpls_nh * ) ( ( rt ) - > rt_nh ) ; \
nhsel < ( rt ) - > rt_nhn ; \
nh + + , nhsel + + )
# define endfor_nexthops(rt) }
2015-03-03 19:10:47 -06:00
static inline struct mpls_shim_hdr * mpls_hdr ( const struct sk_buff * skb )
{
return ( struct mpls_shim_hdr * ) skb_network_header ( skb ) ;
}
static inline struct mpls_shim_hdr mpls_entry_encode ( u32 label , unsigned ttl , unsigned tc , bool bos )
{
struct mpls_shim_hdr result ;
result . label_stack_entry =
cpu_to_be32 ( ( label < < MPLS_LS_LABEL_SHIFT ) |
( tc < < MPLS_LS_TC_SHIFT ) |
( bos ? ( 1 < < MPLS_LS_S_SHIFT ) : 0 ) |
( ttl < < MPLS_LS_TTL_SHIFT ) ) ;
return result ;
}
static inline struct mpls_entry_decoded mpls_entry_decode ( struct mpls_shim_hdr * hdr )
{
struct mpls_entry_decoded result ;
unsigned entry = be32_to_cpu ( hdr - > label_stack_entry ) ;
result . label = ( entry & MPLS_LS_LABEL_MASK ) > > MPLS_LS_LABEL_SHIFT ;
result . ttl = ( entry & MPLS_LS_TTL_MASK ) > > MPLS_LS_TTL_SHIFT ;
result . tc = ( entry & MPLS_LS_TC_MASK ) > > MPLS_LS_TC_SHIFT ;
result . bos = ( entry & MPLS_LS_S_MASK ) > > MPLS_LS_S_SHIFT ;
return result ;
}
2015-07-21 10:43:52 +02:00
int nla_put_labels ( struct sk_buff * skb , int attrtype , u8 labels ,
const u32 label [ ] ) ;
2015-10-23 06:03:27 -07:00
int nla_get_labels ( const struct nlattr * nla , u32 max_labels , u8 * labels ,
2015-07-21 10:43:52 +02:00
u32 label [ ] ) ;
2015-10-23 06:03:27 -07:00
int nla_get_via ( const struct nlattr * nla , u8 * via_alen , u8 * via_table ,
u8 via [ ] ) ;
2015-07-21 10:43:52 +02:00
bool mpls_output_possible ( const struct net_device * dev ) ;
unsigned int mpls_dev_mtu ( const struct net_device * dev ) ;
bool mpls_pkt_too_big ( const struct sk_buff * skb , unsigned int mtu ) ;
2015-03-03 19:13:19 -06:00
2015-03-03 19:10:47 -06:00
# endif /* MPLS_INTERNAL_H */