19b42cabeSNuno Antunes /* 29b42cabeSNuno Antunes * Copyright (c) 2007 The DragonFly Project. All rights reserved. 39b42cabeSNuno Antunes * 49b42cabeSNuno Antunes * Redistribution and use in source and binary forms, with or without 59b42cabeSNuno Antunes * modification, are permitted provided that the following conditions 69b42cabeSNuno Antunes * are met: 79b42cabeSNuno Antunes * 89b42cabeSNuno Antunes * 1. Redistributions of source code must retain the above copyright 99b42cabeSNuno Antunes * notice, this list of conditions and the following disclaimer. 109b42cabeSNuno Antunes * 2. Redistributions in binary form must reproduce the above copyright 119b42cabeSNuno Antunes * notice, this list of conditions and the following disclaimer in 129b42cabeSNuno Antunes * the documentation and/or other materials provided with the 139b42cabeSNuno Antunes * distribution. 149b42cabeSNuno Antunes * 3. Neither the name of The DragonFly Project nor the names of its 159b42cabeSNuno Antunes * contributors may be used to endorse or promote products derived 169b42cabeSNuno Antunes * from this software without specific, prior written permission. 179b42cabeSNuno Antunes * 189b42cabeSNuno Antunes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 199b42cabeSNuno Antunes * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 209b42cabeSNuno Antunes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 219b42cabeSNuno Antunes * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 229b42cabeSNuno Antunes * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 239b42cabeSNuno Antunes * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 249b42cabeSNuno Antunes * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 259b42cabeSNuno Antunes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 269b42cabeSNuno Antunes * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 279b42cabeSNuno Antunes * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 289b42cabeSNuno Antunes * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 299b42cabeSNuno Antunes * SUCH DAMAGE. 309b42cabeSNuno Antunes * 31*cb8d752cSNuno Antunes * $DragonFly: src/sys/netproto/mpls/mpls_demux.c,v 1.2 2008/08/05 15:11:32 nant Exp $ 329b42cabeSNuno Antunes */ 339b42cabeSNuno Antunes 349b42cabeSNuno Antunes #include <sys/mbuf.h> 359b42cabeSNuno Antunes #include <sys/systm.h> /* ncpus2_mask */ 369b42cabeSNuno Antunes #include <sys/types.h> 379b42cabeSNuno Antunes 389b42cabeSNuno Antunes #include <net/netisr.h> 399b42cabeSNuno Antunes 409b42cabeSNuno Antunes #include <netinet/in_var.h> 419b42cabeSNuno Antunes 429b42cabeSNuno Antunes #include <netproto/mpls/mpls.h> 439b42cabeSNuno Antunes #include <netproto/mpls/mpls_var.h> 449b42cabeSNuno Antunes 459b42cabeSNuno Antunes extern struct thread netisr_cpu[]; 469b42cabeSNuno Antunes 479b42cabeSNuno Antunes static __inline int 489b42cabeSNuno Antunes MPLSP_MPORT_HASH(mpls_label_t label, u_short if_index) 499b42cabeSNuno Antunes { 509b42cabeSNuno Antunes /* Use low order byte (demux up to 256 cpus) */ 519b42cabeSNuno Antunes KASSERT(ncpus2 < 256, ("need different hash function")); /* XXX */ 529b42cabeSNuno Antunes #if BYTE_ORDER == LITTLE_ENDIAN 539b42cabeSNuno Antunes label &= 0x00ff0000; 549b42cabeSNuno Antunes label = label >> 16; 559b42cabeSNuno Antunes #endif 569b42cabeSNuno Antunes return ((label ^ if_index) & ncpus2_mask); 579b42cabeSNuno Antunes } 589b42cabeSNuno Antunes 599b42cabeSNuno Antunes boolean_t 609b42cabeSNuno Antunes mpls_lengthcheck(struct mbuf **mp) 619b42cabeSNuno Antunes { 629b42cabeSNuno Antunes struct mbuf *m = *mp; 639b42cabeSNuno Antunes 649b42cabeSNuno Antunes /* The packet must be at least the size of an MPLS header. */ 659b42cabeSNuno Antunes if (m->m_pkthdr.len < sizeof(struct mpls)) { 669b42cabeSNuno Antunes mplsstat.mplss_tooshort++; 679b42cabeSNuno Antunes m_free(m); 689b42cabeSNuno Antunes return FALSE; 699b42cabeSNuno Antunes } 709b42cabeSNuno Antunes 719b42cabeSNuno Antunes /* The MPLS header must reside completely in the first mbuf. */ 729b42cabeSNuno Antunes if (m->m_len < sizeof(struct mpls)) { 739b42cabeSNuno Antunes m = m_pullup(m, sizeof(struct mpls)); 749b42cabeSNuno Antunes if (m == NULL) { 759b42cabeSNuno Antunes mplsstat.mplss_toosmall++; 769b42cabeSNuno Antunes return FALSE; 779b42cabeSNuno Antunes } 789b42cabeSNuno Antunes } 799b42cabeSNuno Antunes 809b42cabeSNuno Antunes *mp = m; 819b42cabeSNuno Antunes return TRUE; 829b42cabeSNuno Antunes } 839b42cabeSNuno Antunes 849b42cabeSNuno Antunes struct lwkt_port * 859b42cabeSNuno Antunes mpls_mport(struct mbuf **mp) 869b42cabeSNuno Antunes { 879b42cabeSNuno Antunes struct mbuf *m = *mp; 889b42cabeSNuno Antunes struct mpls *mpls; 899b42cabeSNuno Antunes mpls_label_t label; 909b42cabeSNuno Antunes struct ifnet *ifp; 919b42cabeSNuno Antunes int cpu; 929b42cabeSNuno Antunes lwkt_port_t port; 939b42cabeSNuno Antunes 949b42cabeSNuno Antunes if (!mpls_lengthcheck(mp)) { 959b42cabeSNuno Antunes *mp = NULL; 969b42cabeSNuno Antunes return (NULL); 979b42cabeSNuno Antunes } 989b42cabeSNuno Antunes 999b42cabeSNuno Antunes mpls = mtod(m, struct mpls *); 1009b42cabeSNuno Antunes 1019b42cabeSNuno Antunes label = MPLS_LABEL(ntohl(mpls->mpls_shim)); 1029b42cabeSNuno Antunes ifp = m->m_pkthdr.rcvif; 1039b42cabeSNuno Antunes cpu = MPLSP_MPORT_HASH(label, ifp->if_index); 1049b42cabeSNuno Antunes port = &netisr_cpu[cpu].td_msgport; 1059b42cabeSNuno Antunes 1069b42cabeSNuno Antunes return (port); 1079b42cabeSNuno Antunes } 1089b42cabeSNuno Antunes 109