1 /* $OpenBSD: mpls.h,v 1.46 2021/05/25 22:45:10 bluhm Exp $ */ 2 3 /* 4 * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULARPURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #ifndef _NETMPLS_MPLS_H_ 34 #define _NETMPLS_MPLS_H_ 35 36 /* 37 * Structure of a SHIM header. 38 */ 39 #define MPLS_LABEL_MAX ((1 << 20) - 1) 40 41 struct shim_hdr { 42 u_int32_t shim_label; /* 20 bit label, 4 bit exp & BoS, 8 bit TTL */ 43 }; 44 45 #define MPLS_HDRLEN sizeof(struct shim_hdr) 46 47 /* 48 * By byte-swapping the constants, we avoid ever having to byte-swap IP 49 * addresses inside the kernel. Unfortunately, user-level programs rely 50 * on these macros not doing byte-swapping. 51 */ 52 53 #ifdef _KERNEL 54 #define __MADDR(x) ((u_int32_t)htonl((u_int32_t)(x))) 55 #else 56 #define __MADDR(x) ((u_int32_t)(x)) 57 #endif 58 59 #define MPLS_LABEL_MASK __MADDR(0xfffff000U) 60 #define MPLS_LABEL_OFFSET 12 61 #define MPLS_EXP_MASK __MADDR(0x00000e00U) 62 #define MPLS_EXP_OFFSET 9 63 #define MPLS_BOS_MASK __MADDR(0x00000100U) 64 #define MPLS_BOS_OFFSET 8 65 #define MPLS_TTL_MASK __MADDR(0x000000ffU) 66 67 #define CW_ZERO_MASK __MADDR(0xf0000000U) 68 #define CW_FRAG_MASK __MADDR(0x00300000U) 69 70 #define MPLS_BOS_ISSET(l) (((l) & MPLS_BOS_MASK) == MPLS_BOS_MASK) 71 72 /* Reserved label values (RFC3032) */ 73 #define MPLS_LABEL_IPV4NULL 0 /* IPv4 Explicit NULL Label */ 74 #define MPLS_LABEL_RTALERT 1 /* Router Alert Label */ 75 #define MPLS_LABEL_IPV6NULL 2 /* IPv6 Explicit NULL Label */ 76 #define MPLS_LABEL_IMPLNULL 3 /* Implicit NULL Label */ 77 /* MPLS_LABEL_RESERVED 4-15 */ /* Values 4-15 are reserved */ 78 #define MPLS_LABEL_RESERVED_MAX 15 79 80 /* 81 * Socket address 82 */ 83 84 struct sockaddr_mpls { 85 u_int8_t smpls_len; /* length */ 86 u_int8_t smpls_family; /* AF_MPLS */ 87 u_int16_t smpls_pad0; 88 u_int32_t smpls_label; /* MPLS label */ 89 u_int32_t smpls_pad1[2]; 90 }; 91 92 struct rt_mpls { 93 u_int32_t mpls_label; 94 u_int8_t mpls_operation; 95 u_int8_t mpls_exp; 96 }; 97 98 #define MPLS_OP_LOCAL 0x0 99 #define MPLS_OP_POP 0x1 100 #define MPLS_OP_PUSH 0x2 101 #define MPLS_OP_SWAP 0x4 102 103 #define MPLS_INKERNEL_LOOP_MAX 16 104 105 #define satosmpls(sa) ((struct sockaddr_mpls *)(sa)) 106 #define smplstosa(smpls) ((struct sockaddr *)(smpls)) 107 108 /* 109 * Names for MPLS sysctl objects 110 */ 111 #define MPLSCTL_ENABLE 1 112 #define MPLSCTL_DEFTTL 2 113 #define MPLSCTL_MAPTTL_IP 5 114 #define MPLSCTL_MAPTTL_IP6 6 115 #define MPLSCTL_MAXID 7 116 117 #define MPLSCTL_NAMES { \ 118 { NULL, 0 }, \ 119 { NULL, 0 }, \ 120 { "ttl", CTLTYPE_INT }, \ 121 { "ifq", CTLTYPE_NODE },\ 122 { NULL, 0 }, \ 123 { "mapttl_ip", CTLTYPE_INT }, \ 124 { "mapttl_ip6", CTLTYPE_INT } \ 125 } 126 127 #define IMR_TYPE_NONE 0 128 #define IMR_TYPE_ETHERNET 1 129 #define IMR_TYPE_ETHERNET_TAGGED 2 130 131 #define IMR_FLAG_CONTROLWORD 0x1 132 133 struct ifmpwreq { 134 uint32_t imr_flags; 135 uint32_t imr_type; /* pseudowire type */ 136 struct shim_hdr imr_lshim; /* local label */ 137 struct shim_hdr imr_rshim; /* remote label */ 138 struct sockaddr_storage imr_nexthop; 139 }; 140 141 #endif 142 143 #ifdef _KERNEL 144 145 #define MPLS_LABEL2SHIM(_l) (htonl((_l) << MPLS_LABEL_OFFSET)) 146 #define MPLS_SHIM2LABEL(_s) (ntohl((_s)) >> MPLS_LABEL_OFFSET) 147 148 extern int mpls_defttl; 149 extern int mpls_mapttl_ip; 150 extern int mpls_mapttl_ip6; 151 152 153 struct mbuf *mpls_shim_pop(struct mbuf *); 154 struct mbuf *mpls_shim_swap(struct mbuf *, struct rt_mpls *); 155 struct mbuf *mpls_shim_push(struct mbuf *, struct rt_mpls *); 156 157 struct mbuf *mpls_ip_adjttl(struct mbuf *, u_int8_t); 158 #ifdef INET6 159 struct mbuf *mpls_ip6_adjttl(struct mbuf *, u_int8_t); 160 #endif 161 162 int mpls_output(struct ifnet *, struct mbuf *, struct sockaddr *, 163 struct rtentry *); 164 void mpls_input(struct ifnet *, struct mbuf *); 165 166 #endif /* _KERNEL */ 167