File: | net/if_mpe.c |
Warning: | line 253, column 2 Value stored to 'error' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: if_mpe.c,v 1.101 2021/11/08 04:50:54 dlg Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@spootnik.org> |
5 | * |
6 | * Permission to use, copy, modify, and distribute this software for any |
7 | * purpose with or without fee is hereby granted, provided that the above |
8 | * copyright notice and this permission notice appear in all copies. |
9 | * |
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 | */ |
18 | |
19 | #include <sys/param.h> |
20 | #include <sys/systm.h> |
21 | #include <sys/mbuf.h> |
22 | #include <sys/socket.h> |
23 | #include <sys/sockio.h> |
24 | #include <sys/ioctl.h> |
25 | |
26 | #include <net/if.h> |
27 | #include <net/if_dl.h> |
28 | #include <net/if_var.h> |
29 | #include <net/if_types.h> |
30 | #include <net/netisr.h> |
31 | #include <net/route.h> |
32 | |
33 | #include <netinet/in.h> |
34 | #include <netinet/ip.h> |
35 | |
36 | #ifdef INET61 |
37 | #include <netinet/ip6.h> |
38 | #endif /* INET6 */ |
39 | |
40 | #include "bpfilter.h" |
41 | #if NBPFILTER1 > 0 |
42 | #include <net/bpf.h> |
43 | #endif |
44 | |
45 | #include <netmpls/mpls.h> |
46 | |
47 | |
48 | |
49 | #ifdef MPLS_DEBUG |
50 | #define DPRINTF(x) do { if (mpedebug) printf x ; } while (0) |
51 | #else |
52 | #define DPRINTF(x) |
53 | #endif |
54 | |
55 | struct mpe_softc { |
56 | struct ifnet sc_if; /* the interface */ |
57 | int sc_txhprio; |
58 | int sc_rxhprio; |
59 | unsigned int sc_rdomain; |
60 | struct ifaddr sc_ifa; |
61 | struct sockaddr_mpls sc_smpls; |
62 | |
63 | int sc_dead; |
64 | }; |
65 | |
66 | #define MPE_HDRLENsizeof(struct shim_hdr) sizeof(struct shim_hdr) |
67 | #define MPE_MTU1500 1500 |
68 | #define MPE_MTU_MIN256 256 |
69 | #define MPE_MTU_MAX8192 8192 |
70 | |
71 | void mpeattach(int); |
72 | int mpe_output(struct ifnet *, struct mbuf *, struct sockaddr *, |
73 | struct rtentry *); |
74 | int mpe_ioctl(struct ifnet *, u_long, caddr_t); |
75 | void mpe_start(struct ifnet *); |
76 | int mpe_clone_create(struct if_clone *, int); |
77 | int mpe_clone_destroy(struct ifnet *); |
78 | void mpe_input(struct ifnet *, struct mbuf *); |
79 | |
80 | struct if_clone mpe_cloner = |
81 | IF_CLONE_INITIALIZER("mpe", mpe_clone_create, mpe_clone_destroy){ .ifc_list = { ((void *)0), ((void *)0) }, .ifc_name = "mpe" , .ifc_namelen = sizeof("mpe") - 1, .ifc_create = mpe_clone_create , .ifc_destroy = mpe_clone_destroy, }; |
82 | |
83 | extern int mpls_mapttl_ip; |
84 | #ifdef INET61 |
85 | extern int mpls_mapttl_ip6; |
86 | #endif |
87 | |
88 | void |
89 | mpeattach(int nmpe) |
90 | { |
91 | if_clone_attach(&mpe_cloner); |
92 | } |
93 | |
94 | int |
95 | mpe_clone_create(struct if_clone *ifc, int unit) |
96 | { |
97 | struct mpe_softc *sc; |
98 | struct ifnet *ifp; |
99 | |
100 | sc = malloc(sizeof(*sc), M_DEVBUF2, M_WAITOK0x0001|M_CANFAIL0x0004|M_ZERO0x0008); |
101 | if (sc == NULL((void *)0)) |
102 | return (ENOMEM12); |
103 | |
104 | ifp = &sc->sc_if; |
105 | snprintf(ifp->if_xname, sizeof ifp->if_xname, "mpe%d", unit); |
106 | ifp->if_flags = IFF_POINTOPOINT0x10; |
107 | ifp->if_xflags = IFXF_CLONED0x2; |
108 | ifp->if_softc = sc; |
109 | ifp->if_mtuif_data.ifi_mtu = MPE_MTU1500; |
110 | ifp->if_ioctl = mpe_ioctl; |
111 | ifp->if_bpf_mtap = p2p_bpf_mtap; |
112 | ifp->if_input = p2p_input; |
113 | ifp->if_output = mpe_output; |
114 | ifp->if_start = mpe_start; |
115 | ifp->if_typeif_data.ifi_type = IFT_MPLS0xa6; |
116 | ifp->if_hdrlenif_data.ifi_hdrlen = MPE_HDRLENsizeof(struct shim_hdr); |
117 | |
118 | sc->sc_dead = 0; |
119 | |
120 | if_attach(ifp); |
121 | if_alloc_sadl(ifp); |
122 | if_counters_alloc(ifp); |
123 | |
124 | #if NBPFILTER1 > 0 |
125 | bpfattach(&ifp->if_bpf, ifp, DLT_LOOP12, sizeof(u_int32_t)); |
126 | #endif |
127 | |
128 | sc->sc_txhprio = 0; |
129 | sc->sc_rxhprio = IF_HDRPRIO_PACKET-1; |
130 | sc->sc_rdomain = 0; |
131 | sc->sc_ifa.ifa_ifp = ifp; |
132 | sc->sc_ifa.ifa_addr = sdltosa(ifp->if_sadl); |
133 | sc->sc_smpls.smpls_len = sizeof(sc->sc_smpls); |
134 | sc->sc_smpls.smpls_family = AF_MPLS33; |
135 | |
136 | return (0); |
137 | } |
138 | |
139 | int |
140 | mpe_clone_destroy(struct ifnet *ifp) |
141 | { |
142 | struct mpe_softc *sc = ifp->if_softc; |
143 | |
144 | NET_LOCK()do { rw_enter_write(&netlock); } while (0); |
145 | CLR(ifp->if_flags, IFF_RUNNING)((ifp->if_flags) &= ~(0x40)); |
146 | sc->sc_dead = 1; |
147 | |
148 | if (sc->sc_smpls.smpls_label) { |
149 | rt_ifa_del(&sc->sc_ifa, RTF_MPLS0x100000|RTF_LOCAL0x200000, |
150 | smplstosa(&sc->sc_smpls)((struct sockaddr *)(&sc->sc_smpls)), sc->sc_rdomain); |
151 | } |
152 | NET_UNLOCK()do { rw_exit_write(&netlock); } while (0); |
153 | |
154 | ifq_barrier(&ifp->if_snd); |
155 | |
156 | if_detach(ifp); |
157 | free(sc, M_DEVBUF2, sizeof *sc); |
158 | return (0); |
159 | } |
160 | |
161 | /* |
162 | * Start output on the mpe interface. |
163 | */ |
164 | void |
165 | mpe_start(struct ifnet *ifp) |
166 | { |
167 | struct mpe_softc *sc = ifp->if_softc; |
168 | struct mbuf *m; |
169 | struct sockaddr *sa; |
170 | struct sockaddr smpls = { .sa_family = AF_MPLS33 }; |
171 | struct rtentry *rt; |
172 | struct ifnet *ifp0; |
173 | |
174 | while ((m = ifq_dequeue(&ifp->if_snd)) != NULL((void *)0)) { |
175 | sa = mtod(m, struct sockaddr *)((struct sockaddr *)((m)->m_hdr.mh_data)); |
176 | rt = rtalloc(sa, RT_RESOLVE1, sc->sc_rdomain); |
177 | if (!rtisvalid(rt)) { |
178 | m_freem(m); |
179 | rtfree(rt); |
180 | continue; |
181 | } |
182 | |
183 | ifp0 = if_get(rt->rt_ifidx); |
184 | if (ifp0 == NULL((void *)0)) { |
185 | m_freem(m); |
186 | rtfree(rt); |
187 | continue; |
188 | } |
189 | |
190 | m_adj(m, sa->sa_len); |
191 | |
192 | #if NBPFILTER1 > 0 |
193 | if (ifp->if_bpf) { |
194 | /* remove MPLS label before passing packet to bpf */ |
195 | m->m_datam_hdr.mh_data += sizeof(struct shim_hdr); |
196 | m->m_lenm_hdr.mh_len -= sizeof(struct shim_hdr); |
197 | m->m_pkthdrM_dat.MH.MH_pkthdr.len -= sizeof(struct shim_hdr); |
198 | bpf_mtap_af(ifp->if_bpf, m->m_pkthdrM_dat.MH.MH_pkthdr.ph_family, |
199 | m, BPF_DIRECTION_OUT(1 << 1)); |
200 | m->m_datam_hdr.mh_data -= sizeof(struct shim_hdr); |
201 | m->m_lenm_hdr.mh_len += sizeof(struct shim_hdr); |
202 | m->m_pkthdrM_dat.MH.MH_pkthdr.len += sizeof(struct shim_hdr); |
203 | } |
204 | #endif |
205 | |
206 | m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid = sc->sc_rdomain; |
207 | CLR(m->m_flags, M_BCAST|M_MCAST)((m->m_hdr.mh_flags) &= ~(0x0100|0x0200)); |
208 | |
209 | mpls_output(ifp0, m, &smpls, rt); |
210 | if_put(ifp0); |
211 | rtfree(rt); |
212 | } |
213 | } |
214 | |
215 | int |
216 | mpe_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, |
217 | struct rtentry *rt) |
218 | { |
219 | struct mpe_softc *sc; |
220 | struct rt_mpls *rtmpls; |
221 | struct shim_hdr shim; |
222 | int error; |
223 | int txprio; |
224 | uint8_t ttl = mpls_defttl; |
225 | uint8_t tos, prio; |
226 | size_t ttloff; |
227 | socklen_t slen; |
228 | |
229 | if (!rtisvalid(rt) || !ISSET(rt->rt_flags, RTF_MPLS)((rt->rt_flags) & (0x100000))) { |
230 | m_freem(m); |
231 | return (ENETUNREACH51); |
232 | } |
233 | |
234 | if (dst->sa_family == AF_LINK18 && ISSET(rt->rt_flags, RTF_LOCAL)((rt->rt_flags) & (0x200000))) { |
235 | mpe_input(ifp, m); |
236 | return (0); |
237 | } |
238 | |
239 | #ifdef DIAGNOSTIC1 |
240 | if (ifp->if_rdomainif_data.ifi_rdomain != rtable_l2(m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid)) { |
241 | printf("%s: trying to send packet on wrong domain. " |
242 | "if %d vs. mbuf %d\n", ifp->if_xname, |
243 | ifp->if_rdomainif_data.ifi_rdomain, rtable_l2(m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid)); |
244 | } |
245 | #endif |
246 | |
247 | rtmpls = (struct rt_mpls *)rt->rt_llinfo; |
248 | if (rtmpls->mpls_operation != MPLS_OP_PUSH0x2) { |
249 | m_freem(m); |
250 | return (ENETUNREACH51); |
251 | } |
252 | |
253 | error = 0; |
Value stored to 'error' is never read | |
254 | switch (dst->sa_family) { |
255 | case AF_INET2: { |
256 | struct ip *ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data)); |
257 | tos = ip->ip_tos; |
258 | ttloff = offsetof(struct ip, ip_ttl)__builtin_offsetof(struct ip, ip_ttl); |
259 | slen = sizeof(struct sockaddr_in); |
260 | break; |
261 | } |
262 | #ifdef INET61 |
263 | case AF_INET624: { |
264 | struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data)); |
265 | uint32_t flow = bemtoh32(&ip6->ip6_flow)(__uint32_t)(__builtin_constant_p(*(__uint32_t *)(&ip6-> ip6_ctlun.ip6_un1.ip6_un1_flow)) ? (__uint32_t)(((__uint32_t) (*(__uint32_t *)(&ip6->ip6_ctlun.ip6_un1.ip6_un1_flow) ) & 0xff) << 24 | ((__uint32_t)(*(__uint32_t *)(& ip6->ip6_ctlun.ip6_un1.ip6_un1_flow)) & 0xff00) << 8 | ((__uint32_t)(*(__uint32_t *)(&ip6->ip6_ctlun.ip6_un1 .ip6_un1_flow)) & 0xff0000) >> 8 | ((__uint32_t)(*( __uint32_t *)(&ip6->ip6_ctlun.ip6_un1.ip6_un1_flow)) & 0xff000000) >> 24) : __swap32md(*(__uint32_t *)(&ip6 ->ip6_ctlun.ip6_un1.ip6_un1_flow))); |
266 | tos = flow >> 20; |
267 | ttloff = offsetof(struct ip6_hdr, ip6_hlim)__builtin_offsetof(struct ip6_hdr, ip6_ctlun.ip6_un1.ip6_un1_hlim ); |
268 | slen = sizeof(struct sockaddr_in6); |
269 | break; |
270 | } |
271 | #endif |
272 | default: |
273 | m_freem(m); |
274 | return (EPFNOSUPPORT46); |
275 | } |
276 | |
277 | if (mpls_mapttl_ip) { |
278 | /* assumes the ip header is already contig */ |
279 | ttl = *(mtod(m, uint8_t *)((uint8_t *)((m)->m_hdr.mh_data)) + ttloff); |
280 | } |
281 | |
282 | sc = ifp->if_softc; |
283 | txprio = sc->sc_txhprio; |
284 | |
285 | switch (txprio) { |
286 | case IF_HDRPRIO_PACKET-1: |
287 | prio = m->m_pkthdrM_dat.MH.MH_pkthdr.pf.prio; |
288 | break; |
289 | case IF_HDRPRIO_PAYLOAD-2: |
290 | prio = IFQ_TOS2PRIO(tos)((tos) >> 5); |
291 | break; |
292 | default: |
293 | prio = txprio; |
294 | break; |
295 | } |
296 | |
297 | shim.shim_label = rtmpls->mpls_label | htonl(prio << MPLS_EXP_OFFSET)(__uint32_t)(__builtin_constant_p(prio << 9) ? (__uint32_t )(((__uint32_t)(prio << 9) & 0xff) << 24 | (( __uint32_t)(prio << 9) & 0xff00) << 8 | ((__uint32_t )(prio << 9) & 0xff0000) >> 8 | ((__uint32_t) (prio << 9) & 0xff000000) >> 24) : __swap32md (prio << 9)) | |
298 | MPLS_BOS_MASK((u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t)(0x00000100U )) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000100U)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000100U)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000100U)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000100U )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x00000100U )))) | htonl(ttl)(__uint32_t)(__builtin_constant_p(ttl) ? (__uint32_t)(((__uint32_t )(ttl) & 0xff) << 24 | ((__uint32_t)(ttl) & 0xff00 ) << 8 | ((__uint32_t)(ttl) & 0xff0000) >> 8 | ((__uint32_t)(ttl) & 0xff000000) >> 24) : __swap32md (ttl)); |
299 | |
300 | m = m_prepend(m, sizeof(shim), M_NOWAIT0x0002); |
301 | if (m == NULL((void *)0)) { |
302 | error = ENOMEM12; |
303 | goto out; |
304 | } |
305 | *mtod(m, struct shim_hdr *)((struct shim_hdr *)((m)->m_hdr.mh_data)) = shim; |
306 | |
307 | m = m_prepend(m, slen, M_WAITOK0x0001); |
308 | if (m == NULL((void *)0)) { |
309 | error = ENOMEM12; |
310 | goto out; |
311 | } |
312 | memcpy(mtod(m, struct sockaddr *), rt->rt_gateway, slen)__builtin_memcpy((((struct sockaddr *)((m)->m_hdr.mh_data) )), (rt->rt_gateway), (slen)); |
313 | mtod(m, struct sockaddr *)((struct sockaddr *)((m)->m_hdr.mh_data))->sa_len = slen; /* to be sure */ |
314 | |
315 | m->m_pkthdrM_dat.MH.MH_pkthdr.ph_family = dst->sa_family; |
316 | |
317 | error = if_enqueue(ifp, m); |
318 | out: |
319 | if (error) |
320 | ifp->if_oerrorsif_data.ifi_oerrors++; |
321 | return (error); |
322 | } |
323 | |
324 | int |
325 | mpe_set_label(struct mpe_softc *sc, uint32_t label, unsigned int rdomain) |
326 | { |
327 | int error; |
328 | |
329 | if (sc->sc_dead) |
330 | return (ENXIO6); |
331 | |
332 | if (sc->sc_smpls.smpls_label) { |
333 | /* remove old MPLS route */ |
334 | rt_ifa_del(&sc->sc_ifa, RTF_MPLS0x100000|RTF_LOCAL0x200000, |
335 | smplstosa(&sc->sc_smpls)((struct sockaddr *)(&sc->sc_smpls)), sc->sc_rdomain); |
336 | } |
337 | |
338 | /* add new MPLS route */ |
339 | sc->sc_smpls.smpls_label = label; |
340 | sc->sc_rdomain = rdomain; |
341 | |
342 | /* only install with a label or mpe_clone_destroy() will ignore it */ |
343 | if (sc->sc_smpls.smpls_label == MPLS_LABEL2SHIM(0)((__uint32_t)(__builtin_constant_p((0) << 12) ? (__uint32_t )(((__uint32_t)((0) << 12) & 0xff) << 24 | (( __uint32_t)((0) << 12) & 0xff00) << 8 | ((__uint32_t )((0) << 12) & 0xff0000) >> 8 | ((__uint32_t) ((0) << 12) & 0xff000000) >> 24) : __swap32md ((0) << 12)))) |
344 | return 0; |
345 | |
346 | error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS0x100000|RTF_LOCAL0x200000, |
347 | smplstosa(&sc->sc_smpls)((struct sockaddr *)(&sc->sc_smpls)), sc->sc_rdomain); |
348 | if (error) |
349 | sc->sc_smpls.smpls_label = 0; |
350 | |
351 | return (error); |
352 | } |
353 | |
354 | int |
355 | mpe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) |
356 | { |
357 | struct mpe_softc *sc = ifp->if_softc; |
358 | struct ifreq *ifr; |
359 | struct shim_hdr shim; |
360 | int error = 0; |
361 | |
362 | ifr = (struct ifreq *)data; |
363 | switch (cmd) { |
364 | case SIOCSIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((12))): |
365 | break; |
366 | case SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((16))): |
367 | if (ifp->if_flags & IFF_UP0x1) |
368 | ifp->if_flags |= IFF_RUNNING0x40; |
369 | else |
370 | ifp->if_flags &= ~IFF_RUNNING0x40; |
371 | break; |
372 | case SIOCSIFMTU((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((127))): |
373 | if (ifr->ifr_mtuifr_ifru.ifru_metric < MPE_MTU_MIN256 || |
374 | ifr->ifr_mtuifr_ifru.ifru_metric > MPE_MTU_MAX8192) |
375 | error = EINVAL22; |
376 | else |
377 | ifp->if_mtuif_data.ifi_mtu = ifr->ifr_mtuifr_ifru.ifru_metric; |
378 | break; |
379 | case SIOCGETLABEL((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((154))): |
380 | shim.shim_label = MPLS_SHIM2LABEL(sc->sc_smpls.smpls_label)((__uint32_t)(__builtin_constant_p((sc->sc_smpls.smpls_label )) ? (__uint32_t)(((__uint32_t)((sc->sc_smpls.smpls_label) ) & 0xff) << 24 | ((__uint32_t)((sc->sc_smpls.smpls_label )) & 0xff00) << 8 | ((__uint32_t)((sc->sc_smpls. smpls_label)) & 0xff0000) >> 8 | ((__uint32_t)((sc-> sc_smpls.smpls_label)) & 0xff000000) >> 24) : __swap32md ((sc->sc_smpls.smpls_label))) >> 12); |
381 | if (shim.shim_label == 0) { |
382 | error = EADDRNOTAVAIL49; |
383 | break; |
384 | } |
385 | error = copyout(&shim, ifr->ifr_dataifr_ifru.ifru_data, sizeof(shim)); |
386 | break; |
387 | case SIOCSETLABEL((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((153))): |
388 | error = copyin(ifr->ifr_dataifr_ifru.ifru_data, &shim, sizeof(shim)); |
389 | if (error != 0) |
390 | break; |
391 | if (shim.shim_label > MPLS_LABEL_MAX((1 << 20) - 1) || |
392 | shim.shim_label <= MPLS_LABEL_RESERVED_MAX15) { |
393 | error = EINVAL22; |
394 | break; |
395 | } |
396 | shim.shim_label = MPLS_LABEL2SHIM(shim.shim_label)((__uint32_t)(__builtin_constant_p((shim.shim_label) << 12) ? (__uint32_t)(((__uint32_t)((shim.shim_label) << 12 ) & 0xff) << 24 | ((__uint32_t)((shim.shim_label) << 12) & 0xff00) << 8 | ((__uint32_t)((shim.shim_label ) << 12) & 0xff0000) >> 8 | ((__uint32_t)((shim .shim_label) << 12) & 0xff000000) >> 24) : __swap32md ((shim.shim_label) << 12))); |
397 | if (sc->sc_smpls.smpls_label != shim.shim_label) { |
398 | error = mpe_set_label(sc, shim.shim_label, |
399 | sc->sc_rdomain); |
400 | } |
401 | break; |
402 | case SIOCDELLABEL((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((151))): |
403 | if (sc->sc_smpls.smpls_label != MPLS_LABEL2SHIM(0)((__uint32_t)(__builtin_constant_p((0) << 12) ? (__uint32_t )(((__uint32_t)((0) << 12) & 0xff) << 24 | (( __uint32_t)((0) << 12) & 0xff00) << 8 | ((__uint32_t )((0) << 12) & 0xff0000) >> 8 | ((__uint32_t) ((0) << 12) & 0xff000000) >> 24) : __swap32md ((0) << 12)))) { |
404 | rt_ifa_del(&sc->sc_ifa, RTF_MPLS0x100000|RTF_LOCAL0x200000, |
405 | smplstosa(&sc->sc_smpls)((struct sockaddr *)(&sc->sc_smpls)), sc->sc_rdomain); |
406 | } |
407 | sc->sc_smpls.smpls_label = MPLS_LABEL2SHIM(0)((__uint32_t)(__builtin_constant_p((0) << 12) ? (__uint32_t )(((__uint32_t)((0) << 12) & 0xff) << 24 | (( __uint32_t)((0) << 12) & 0xff00) << 8 | ((__uint32_t )((0) << 12) & 0xff0000) >> 8 | ((__uint32_t) ((0) << 12) & 0xff000000) >> 24) : __swap32md ((0) << 12))); |
408 | break; |
409 | |
410 | case SIOCSLIFPHYRTABLE((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((161))): |
411 | if (ifr->ifr_rdomainidifr_ifru.ifru_metric < 0 || |
412 | ifr->ifr_rdomainidifr_ifru.ifru_metric > RT_TABLEID_MAX255 || |
413 | !rtable_exists(ifr->ifr_rdomainidifr_ifru.ifru_metric) || |
414 | ifr->ifr_rdomainidifr_ifru.ifru_metric != rtable_l2(ifr->ifr_rdomainidifr_ifru.ifru_metric)) { |
415 | error = EINVAL22; |
416 | break; |
417 | } |
418 | if (sc->sc_rdomain != ifr->ifr_rdomainidifr_ifru.ifru_metric) { |
419 | error = mpe_set_label(sc, sc->sc_smpls.smpls_label, |
420 | ifr->ifr_rdomainidifr_ifru.ifru_metric); |
421 | } |
422 | break; |
423 | case SIOCGLIFPHYRTABLE(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct ifreq) & 0x1fff) << 16) | ((('i')) << 8) | ((162))): |
424 | ifr->ifr_rdomainidifr_ifru.ifru_metric = sc->sc_rdomain; |
425 | break; |
426 | |
427 | case SIOCSTXHPRIO((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((197))): |
428 | error = if_txhprio_l3_check(ifr->ifr_hdrprioifr_ifru.ifru_metric); |
429 | if (error != 0) |
430 | break; |
431 | |
432 | sc->sc_txhprio = ifr->ifr_hdrprioifr_ifru.ifru_metric; |
433 | break; |
434 | case SIOCGTXHPRIO(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct ifreq) & 0x1fff) << 16) | ((('i')) << 8) | ((198))): |
435 | ifr->ifr_hdrprioifr_ifru.ifru_metric = sc->sc_txhprio; |
436 | break; |
437 | |
438 | case SIOCSRXHPRIO((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((219))): |
439 | error = if_rxhprio_l3_check(ifr->ifr_hdrprioifr_ifru.ifru_metric); |
440 | if (error != 0) |
441 | break; |
442 | |
443 | sc->sc_rxhprio = ifr->ifr_hdrprioifr_ifru.ifru_metric; |
444 | break; |
445 | case SIOCGRXHPRIO(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct ifreq) & 0x1fff) << 16) | ((('i')) << 8) | ((219))): |
446 | ifr->ifr_hdrprioifr_ifru.ifru_metric = sc->sc_rxhprio; |
447 | break; |
448 | |
449 | default: |
450 | return (ENOTTY25); |
451 | } |
452 | |
453 | return (error); |
454 | } |
455 | |
456 | void |
457 | mpe_input(struct ifnet *ifp, struct mbuf *m) |
458 | { |
459 | struct mpe_softc *sc = ifp->if_softc; |
460 | struct shim_hdr *shim; |
461 | struct mbuf *n; |
462 | uint8_t ttl, tos; |
463 | uint32_t exp; |
464 | int rxprio = sc->sc_rxhprio; |
465 | |
466 | shim = mtod(m, struct shim_hdr *)((struct shim_hdr *)((m)->m_hdr.mh_data)); |
467 | exp = ntohl(shim->shim_label & MPLS_EXP_MASK)(__uint32_t)(__builtin_constant_p(shim->shim_label & ( (u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t)(0x00000e00U )) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000e00U)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000e00U)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000e00U)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x00000e00U ))))) ? (__uint32_t)(((__uint32_t)(shim->shim_label & ( (u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t)(0x00000e00U )) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000e00U)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000e00U)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000e00U)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x00000e00U ))))) & 0xff) << 24 | ((__uint32_t)(shim->shim_label & ((u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t )(0x00000e00U)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x00000e00U ))))) & 0xff00) << 8 | ((__uint32_t)(shim->shim_label & ((u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t )(0x00000e00U)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x00000e00U ))))) & 0xff0000) >> 8 | ((__uint32_t)(shim->shim_label & ((u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t )(0x00000e00U)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x00000e00U ))))) & 0xff000000) >> 24) : __swap32md(shim->shim_label & ((u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t )(0x00000e00U)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000e00U )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x00000e00U )))))) >> MPLS_EXP_OFFSET9; |
468 | if (!MPLS_BOS_ISSET(shim->shim_label)(((shim->shim_label) & ((u_int32_t)(__uint32_t)(__builtin_constant_p ((u_int32_t)(0x00000100U)) ? (__uint32_t)(((__uint32_t)((u_int32_t )(0x00000100U)) & 0xff) << 24 | ((__uint32_t)((u_int32_t )(0x00000100U)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t )(0x00000100U)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t )(0x00000100U)) & 0xff000000) >> 24) : __swap32md(( u_int32_t)(0x00000100U))))) == ((u_int32_t)(__uint32_t)(__builtin_constant_p ((u_int32_t)(0x00000100U)) ? (__uint32_t)(((__uint32_t)((u_int32_t )(0x00000100U)) & 0xff) << 24 | ((__uint32_t)((u_int32_t )(0x00000100U)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t )(0x00000100U)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t )(0x00000100U)) & 0xff000000) >> 24) : __swap32md(( u_int32_t)(0x00000100U)))))) |
469 | goto drop; |
470 | |
471 | ttl = ntohl(shim->shim_label & MPLS_TTL_MASK)(__uint32_t)(__builtin_constant_p(shim->shim_label & ( (u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t)(0x000000ffU )) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x000000ffU)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x000000ffU)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x000000ffU)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x000000ffU ))))) ? (__uint32_t)(((__uint32_t)(shim->shim_label & ( (u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t)(0x000000ffU )) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x000000ffU)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x000000ffU)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x000000ffU)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x000000ffU ))))) & 0xff) << 24 | ((__uint32_t)(shim->shim_label & ((u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t )(0x000000ffU)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x000000ffU ))))) & 0xff00) << 8 | ((__uint32_t)(shim->shim_label & ((u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t )(0x000000ffU)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x000000ffU ))))) & 0xff0000) >> 8 | ((__uint32_t)(shim->shim_label & ((u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t )(0x000000ffU)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x000000ffU ))))) & 0xff000000) >> 24) : __swap32md(shim->shim_label & ((u_int32_t)(__uint32_t)(__builtin_constant_p((u_int32_t )(0x000000ffU)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x000000ffU )) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x000000ffU )))))); |
472 | m_adj(m, sizeof(*shim)); |
473 | |
474 | n = m; |
475 | while (n->m_lenm_hdr.mh_len == 0) { |
476 | n = n->m_nextm_hdr.mh_next; |
477 | if (n == NULL((void *)0)) |
478 | goto drop; |
479 | } |
480 | |
481 | switch (*mtod(n, uint8_t *)((uint8_t *)((n)->m_hdr.mh_data)) >> 4) { |
482 | case 4: { |
483 | struct ip *ip; |
484 | if (m->m_lenm_hdr.mh_len < sizeof(*ip)) { |
485 | m = m_pullup(m, sizeof(*ip)); |
486 | if (m == NULL((void *)0)) |
487 | return; |
488 | } |
489 | ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data)); |
490 | tos = ip->ip_tos; |
491 | |
492 | if (mpls_mapttl_ip) { |
493 | m = mpls_ip_adjttl(m, ttl); |
494 | if (m == NULL((void *)0)) |
495 | return; |
496 | } |
497 | |
498 | m->m_pkthdrM_dat.MH.MH_pkthdr.ph_family = AF_INET2; |
499 | break; |
500 | } |
501 | #ifdef INET61 |
502 | case 6: { |
503 | struct ip6_hdr *ip6; |
504 | uint32_t flow; |
505 | if (m->m_lenm_hdr.mh_len < sizeof(*ip6)) { |
506 | m = m_pullup(m, sizeof(*ip6)); |
507 | if (m == NULL((void *)0)) |
508 | return; |
509 | } |
510 | ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data)); |
511 | flow = bemtoh32(&ip6->ip6_flow)(__uint32_t)(__builtin_constant_p(*(__uint32_t *)(&ip6-> ip6_ctlun.ip6_un1.ip6_un1_flow)) ? (__uint32_t)(((__uint32_t) (*(__uint32_t *)(&ip6->ip6_ctlun.ip6_un1.ip6_un1_flow) ) & 0xff) << 24 | ((__uint32_t)(*(__uint32_t *)(& ip6->ip6_ctlun.ip6_un1.ip6_un1_flow)) & 0xff00) << 8 | ((__uint32_t)(*(__uint32_t *)(&ip6->ip6_ctlun.ip6_un1 .ip6_un1_flow)) & 0xff0000) >> 8 | ((__uint32_t)(*( __uint32_t *)(&ip6->ip6_ctlun.ip6_un1.ip6_un1_flow)) & 0xff000000) >> 24) : __swap32md(*(__uint32_t *)(&ip6 ->ip6_ctlun.ip6_un1.ip6_un1_flow))); |
512 | tos = flow >> 20; |
513 | |
514 | if (mpls_mapttl_ip6) { |
515 | m = mpls_ip6_adjttl(m, ttl); |
516 | if (m == NULL((void *)0)) |
517 | return; |
518 | } |
519 | |
520 | m->m_pkthdrM_dat.MH.MH_pkthdr.ph_family = AF_INET624; |
521 | break; |
522 | } |
523 | #endif /* INET6 */ |
524 | default: |
525 | goto drop; |
526 | } |
527 | |
528 | switch (rxprio) { |
529 | case IF_HDRPRIO_PACKET-1: |
530 | /* nop */ |
531 | break; |
532 | case IF_HDRPRIO_OUTER-3: |
533 | m->m_pkthdrM_dat.MH.MH_pkthdr.pf.prio = exp; |
534 | break; |
535 | case IF_HDRPRIO_PAYLOAD-2: |
536 | m->m_pkthdrM_dat.MH.MH_pkthdr.pf.prio = IFQ_TOS2PRIO(tos)((tos) >> 5); |
537 | break; |
538 | default: |
539 | m->m_pkthdrM_dat.MH.MH_pkthdr.pf.prio = rxprio; |
540 | break; |
541 | } |
542 | |
543 | if_vinput(ifp, m); |
544 | return; |
545 | drop: |
546 | m_freem(m); |
547 | } |