From owner-svn-soc-all@freebsd.org Mon May 21 19:37:16 2018 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 85FD0EFCD65 for ; Mon, 21 May 2018 19:37:16 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from mxrelay.ysv.freebsd.org (mxrelay.ysv.freebsd.org [IPv6:2001:1900:2254:206a::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.ysv.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 0F77C6D5CD for ; Mon, 21 May 2018 19:37:16 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.ysv.freebsd.org (Postfix) with ESMTPS id 5A48827B95 for ; Mon, 21 May 2018 19:37:15 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id w4LJbFgl072379 for ; Mon, 21 May 2018 19:37:15 GMT (envelope-from sduo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id w4LJbBrV072267 for svn-soc-all@FreeBSD.org; Mon, 21 May 2018 19:37:11 GMT (envelope-from sduo@FreeBSD.org) Date: Mon, 21 May 2018 19:37:11 GMT Message-Id: <201805211937.w4LJbBrV072267@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to sduo@FreeBSD.org using -f From: sduo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r337244 - in soc2018/sduo/head/sys: amd64/conf conf dev/vale_vlan modules/vale_vlan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 May 2018 19:37:16 -0000 Author: sduo Date: Mon May 21 19:37:09 2018 New Revision: 337244 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337244 Log: An hardcoded VLAN configuration can be created, and destroyed, through write and read calls on a special device. Changed sys/conf/files and created a new kernel configuration files to add the vale_vlan module to the kernel. Added: soc2018/sduo/head/sys/amd64/conf/VV_CONF soc2018/sduo/head/sys/dev/vale_vlan/ soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan_freebsd.c soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan_kern.h soc2018/sduo/head/sys/dev/vale_vlan/vv_freebsd_interface.c soc2018/sduo/head/sys/dev/vale_vlan/vv_os_interface.h soc2018/sduo/head/sys/modules/vale_vlan/ soc2018/sduo/head/sys/modules/vale_vlan/Makefile Modified: soc2018/sduo/head/sys/conf/files Added: soc2018/sduo/head/sys/amd64/conf/VV_CONF ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2018/sduo/head/sys/amd64/conf/VV_CONF Mon May 21 19:37:09 2018 (r337244) @@ -0,0 +1,375 @@ +# +# GENERIC -- Generic kernel configuration file for FreeBSD/amd64 +# +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: +# +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD: soc2018/sduo/head/sys/amd64/conf/GENERIC 336667 2018-04-26 16:59:06Z sbruno $ + +cpu HAMMER +ident GENERIC + +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +makeoptions WITH_CTF=1 # Run ctfconvert(1) for DTrace support + +options SCHED_ULE # ULE scheduler +options PREEMPTION # Enable kernel thread preemption +options VIMAGE # Subsystem virtualization, e.g. VNET +options INET # InterNETworking +options INET6 # IPv6 communications protocols +options IPSEC # IP (v4/v6) security +options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 +options TCP_OFFLOAD # TCP offload +options TCP_BLACKBOX # Enhanced TCP event logging +options TCP_HHOOK # hhook(9) framework for TCP +options TCP_RFC7413 # TCP Fast Open +options SCTP # Stream Control Transmission Protocol +options FFS # Berkeley Fast Filesystem +options SOFTUPDATES # Enable FFS soft updates support +options UFS_ACL # Support for access control lists +options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options MD_ROOT # MD is a potential root device +options NFSCL # Network Filesystem Client +options NFSD # Network Filesystem Server +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +options PROCFS # Process filesystem (requires PSEUDOFS) +options PSEUDOFS # Pseudo-filesystem framework +options GEOM_PART_GPT # GUID Partition Tables. +options GEOM_RAID # Soft RAID functionality. +options GEOM_LABEL # Provides labelization +options COMPAT_FREEBSD32 # Compatible with i386 binaries +options COMPAT_FREEBSD4 # Compatible with FreeBSD4 +options COMPAT_FREEBSD5 # Compatible with FreeBSD5 +options COMPAT_FREEBSD6 # Compatible with FreeBSD6 +options COMPAT_FREEBSD7 # Compatible with FreeBSD7 +options COMPAT_FREEBSD9 # Compatible with FreeBSD9 +options COMPAT_FREEBSD10 # Compatible with FreeBSD10 +options COMPAT_FREEBSD11 # Compatible with FreeBSD11 +options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI +options KTRACE # ktrace(1) support +options STACK # stack(9) support +options SYSVSHM # SYSV-style shared memory +options SYSVMSG # SYSV-style message queues +options SYSVSEM # SYSV-style semaphores +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) +options AUDIT # Security event auditing +options CAPABILITY_MODE # Capsicum capability mode +options CAPABILITIES # Capsicum capabilities +options MAC # TrustedBSD MAC Framework +options KDTRACE_FRAME # Ensure frames are compiled in +options KDTRACE_HOOKS # Kernel DTrace hooks +options DDB_CTF # Kernel ELF linker loads CTF data +options INCLUDE_CONFIG_FILE # Include this file in kernel +options RACCT # Resource accounting framework +options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default +options RCTL # Resource limits + +# Debugging support. Always need this: +options KDB # Enable kernel debugger support. +options KDB_TRACE # Print a stack trace for a panic. +# For full debugger support use (turn off in stable branch): +options BUF_TRACKING # Track buffer history +options DDB # Support DDB. +options FULL_BUF_TRACKING # Track more buffer history +options GDB # Support remote GDB. +options DEADLKRES # Enable the deadlock resolver +options INVARIANTS # Enable calls of extra sanity checking +options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +options WITNESS # Enable checks to detect deadlocks and cycles +options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones + +# Make an SMP-capable kernel by default +options SMP # Symmetric MultiProcessor Kernel +options EARLY_AP_STARTUP + +# CPU frequency control +device cpufreq + +# Bus support. +device acpi +options ACPI_DMAR +device pci +options PCI_HP # PCI-Express native HotPlug +options PCI_IOV # PCI SR-IOV support + +# Floppy drives +device fdc + +# ATA controllers +device ahci # AHCI-compatible SATA controllers +device ata # Legacy ATA/SATA controllers +device mvs # Marvell 88SX50XX/88SX60XX/88SX70XX/SoC SATA +device siis # SiliconImage SiI3124/SiI3132/SiI3531 SATA + +# SCSI Controllers +device ahc # AHA2940 and onboard AIC7xxx devices +device ahd # AHA39320/29320 and onboard AIC79xx devices +device esp # AMD Am53C974 (Tekram DC-390(T)) +device hptiop # Highpoint RocketRaid 3xxx series +device isp # Qlogic family +#device ispfw # Firmware for QLogic HBAs- normally a module +device mpt # LSI-Logic MPT-Fusion +device mps # LSI-Logic MPT-Fusion 2 +device mpr # LSI-Logic MPT-Fusion 3 +#device ncr # NCR/Symbios Logic +device sym # NCR/Symbios Logic (newer chipsets + those of `ncr') +device trm # Tekram DC395U/UW/F DC315U adapters + +device adv # Advansys SCSI adapters +device adw # Advansys wide SCSI adapters +device aic # Adaptec 15[012]x SCSI adapters, AIC-6[23]60. +device bt # Buslogic/Mylex MultiMaster SCSI adapters +device isci # Intel C600 SAS controller +device ocs_fc # Emulex FC adapters + +# ATA/SCSI peripherals +device scbus # SCSI bus (required for ATA/SCSI) +device ch # SCSI media changers +device da # Direct Access (disks) +device sa # Sequential Access (tape etc) +device cd # CD +device pass # Passthrough device (direct ATA/SCSI access) +device ses # Enclosure Services (SES and SAF-TE) +#device ctl # CAM Target Layer + +# RAID controllers interfaced to the SCSI subsystem +device amr # AMI MegaRAID +device arcmsr # Areca SATA II RAID +device ciss # Compaq Smart RAID 5* +device dpt # DPT Smartcache III, IV - See NOTES for options +device hptmv # Highpoint RocketRAID 182x +device hptnr # Highpoint DC7280, R750 +device hptrr # Highpoint RocketRAID 17xx, 22xx, 23xx, 25xx +device hpt27xx # Highpoint RocketRAID 27xx +device iir # Intel Integrated RAID +device ips # IBM (Adaptec) ServeRAID +device mly # Mylex AcceleRAID/eXtremeRAID +device twa # 3ware 9000 series PATA/SATA RAID +device smartpqi # Microsemi smartpqi driver +device tws # LSI 3ware 9750 SATA+SAS 6Gb/s RAID controller + +# RAID controllers +device aac # Adaptec FSA RAID +device aacp # SCSI passthrough for aac (requires CAM) +device aacraid # Adaptec by PMC RAID +device ida # Compaq Smart RAID +device mfi # LSI MegaRAID SAS +device mlx # Mylex DAC960 family +device mrsas # LSI/Avago MegaRAID SAS/SATA, 6Gb/s and 12Gb/s +device pmspcv # PMC-Sierra SAS/SATA Controller driver +#XXX pointer/int warnings +#device pst # Promise Supertrak SX6000 +device twe # 3ware ATA RAID + +# NVM Express (NVMe) support +device nvme # base NVMe driver +device nvd # expose NVMe namespaces as disks, depends on nvme + +# atkbdc0 controls both the keyboard and the PS/2 mouse +device atkbdc # AT keyboard controller +device atkbd # AT keyboard +device psm # PS/2 mouse + +device kbdmux # keyboard multiplexer + +device vga # VGA video card driver +options VESA # Add support for VESA BIOS Extensions (VBE) + +device splash # Splash screen and screen saver support + +# syscons is the default console driver, resembling an SCO console +device sc +options SC_PIXEL_MODE # add support for the raster text mode + +# vt is the new video console driver +device vt +device vt_vga +device vt_efifb + +device agp # support several AGP chipsets + +# PCCARD (PCMCIA) support +# PCMCIA and cardbus bridge support +device cbb # cardbus (yenta) bridge +device pccard # PC Card (16-bit) bus +device cardbus # CardBus (32-bit) bus + +# Serial (COM) ports +device uart # Generic UART driver + +# Parallel port +device ppc +device ppbus # Parallel port bus (required) +device lpt # Printer +device ppi # Parallel port interface device +#device vpo # Requires scbus and da + +device puc # Multi I/O cards and multi-channel UARTs + +# PCI Ethernet NICs. +device bxe # Broadcom NetXtreme II BCM5771X/BCM578XX 10GbE +device de # DEC/Intel DC21x4x (``Tulip'') +device em # Intel PRO/1000 Gigabit Ethernet Family +device ix # Intel PRO/10GbE PCIE PF Ethernet +device ixv # Intel PRO/10GbE PCIE VF Ethernet +device ixl # Intel XL710 40Gbe PCIE Ethernet +options IXL_IW # Enable iWARP Client Interface in ixl(4) +device ixlv # Intel XL710 40Gbe VF PCIE Ethernet +device le # AMD Am7900 LANCE and Am79C9xx PCnet +device ti # Alteon Networks Tigon I/II gigabit Ethernet +device txp # 3Com 3cR990 (``Typhoon'') +device vx # 3Com 3c590, 3c595 (``Vortex'') + +# PCI Ethernet NICs that use the common MII bus controller code. +# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs! +device miibus # MII bus support +device ae # Attansic/Atheros L2 FastEthernet +device age # Attansic/Atheros L1 Gigabit Ethernet +device alc # Atheros AR8131/AR8132 Ethernet +device ale # Atheros AR8121/AR8113/AR8114 Ethernet +device bce # Broadcom BCM5706/BCM5708 Gigabit Ethernet +device bfe # Broadcom BCM440x 10/100 Ethernet +device bge # Broadcom BCM570xx Gigabit Ethernet +device cas # Sun Cassini/Cassini+ and NS DP83065 Saturn +device dc # DEC/Intel 21143 and various workalikes +device et # Agere ET1310 10/100/Gigabit Ethernet +device fxp # Intel EtherExpress PRO/100B (82557, 82558) +device gem # Sun GEM/Sun ERI/Apple GMAC +device hme # Sun HME (Happy Meal Ethernet) +device jme # JMicron JMC250 Gigabit/JMC260 Fast Ethernet +device lge # Level 1 LXT1001 gigabit Ethernet +device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet +device nfe # nVidia nForce MCP on-board Ethernet +device nge # NatSemi DP83820 gigabit Ethernet +device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le') +device re # RealTek 8139C+/8169/8169S/8110S +device rl # RealTek 8129/8139 +device sf # Adaptec AIC-6915 (``Starfire'') +device sge # Silicon Integrated Systems SiS190/191 +device sis # Silicon Integrated Systems SiS 900/SiS 7016 +device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet +device ste # Sundance ST201 (D-Link DFE-550TX) +device stge # Sundance/Tamarack TC9021 gigabit Ethernet +device tl # Texas Instruments ThunderLAN +device tx # SMC EtherPower II (83c170 ``EPIC'') +device vge # VIA VT612x gigabit Ethernet +device vr # VIA Rhine, Rhine II +device wb # Winbond W89C840F +device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') + +# Wireless NIC cards +device wlan # 802.11 support +options IEEE80211_DEBUG # enable debug msgs +options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's +options IEEE80211_SUPPORT_MESH # enable 802.11s draft support +device wlan_wep # 802.11 WEP support +device wlan_ccmp # 802.11 CCMP support +device wlan_tkip # 802.11 TKIP support +device wlan_amrr # AMRR transmit rate control algorithm +device an # Aironet 4500/4800 802.11 wireless NICs. +device ath # Atheros NICs +device ath_pci # Atheros pci/cardbus glue +device ath_hal # pci/cardbus chip support +options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors +options AH_AR5416_INTERRUPT_MITIGATION # AR5416 interrupt mitigation +options ATH_ENABLE_11N # Enable 802.11n support for AR5416 and later +device ath_rate_sample # SampleRate tx rate control for ath +#device bwi # Broadcom BCM430x/BCM431x wireless NICs. +#device bwn # Broadcom BCM43xx wireless NICs. +device ipw # Intel 2100 wireless NICs. +device iwi # Intel 2200BG/2225BG/2915ABG wireless NICs. +device iwn # Intel 4965/1000/5000/6000 wireless NICs. +device malo # Marvell Libertas wireless NICs. +device mwl # Marvell 88W8363 802.11n wireless NICs. +device ral # Ralink Technology RT2500 wireless NICs. +device wi # WaveLAN/Intersil/Symbol 802.11 wireless NICs. +device wpi # Intel 3945ABG wireless NICs. + +# Pseudo devices. +device loop # Network loopback +device random # Entropy device +device padlock_rng # VIA Padlock RNG +device rdrand_rng # Intel Bull Mountain RNG +device ether # Ethernet support +device vlan # 802.1Q VLAN support +device tun # Packet tunnel. +device md # Memory "disks" +device gif # IPv6 and IPv4 tunneling +device firmware # firmware assist module + +# The `bpf' device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +# Note that 'bpf' is required for DHCP. +device bpf # Berkeley packet filter + +# USB support +options USB_DEBUG # enable debug msgs +device uhci # UHCI PCI->USB interface +device ohci # OHCI PCI->USB interface +device ehci # EHCI PCI->USB interface (USB 2.0) +device xhci # XHCI PCI->USB interface (USB 3.0) +device usb # USB Bus (required) +device ukbd # Keyboard +device umass # Disks/Mass storage - Requires scbus and da + +# Sound support +device sound # Generic sound driver (required) +device snd_cmi # CMedia CMI8338/CMI8738 +device snd_csa # Crystal Semiconductor CS461x/428x +device snd_emu10kx # Creative SoundBlaster Live! and Audigy +device snd_es137x # Ensoniq AudioPCI ES137x +device snd_hda # Intel High Definition Audio +device snd_ich # Intel, NVidia and other ICH AC'97 Audio +device snd_via8233 # VIA VT8233x Audio + +# MMC/SD +device mmc # MMC/SD bus +device mmcsd # MMC/SD memory card +device sdhci # Generic PCI SD Host Controller + +# VirtIO support +device virtio # Generic VirtIO bus (required) +device virtio_pci # VirtIO PCI device +device vtnet # VirtIO Ethernet device +device virtio_blk # VirtIO Block device +device virtio_scsi # VirtIO SCSI device +device virtio_balloon # VirtIO Memory Balloon device + +# HyperV drivers and enhancement support +device hyperv # HyperV drivers + +# Xen HVM Guest Optimizations +# NOTE: XENHVM depends on xenpci. They must be added or removed together. +options XENHVM # Xen HVM kernel infrastructure +device xenpci # Xen HVM Hypervisor services driver + +# VMware support +device vmx # VMware VMXNET3 Ethernet + +# Netmap provides direct access to TX/RX rings on supported NICs +device netmap # netmap(4) support +device vale_vlan + +# The crypto framework is required by IPSEC +device crypto # Required by IPSEC Modified: soc2018/sduo/head/sys/conf/files ============================================================================== --- soc2018/sduo/head/sys/conf/files Sun May 20 20:44:49 2018 (r337243) +++ soc2018/sduo/head/sys/conf/files Mon May 21 19:37:09 2018 (r337244) @@ -2538,6 +2538,9 @@ dev/netmap/netmap_pt.c optional netmap dev/netmap/netmap_vale.c optional netmap dev/netmap/netmap_legacy.c optional netmap +dev/vale_vlan/vale_vlan.c optional vale_vlan +dev/vale_vlan/vv_freebsd_interface.c optional vale_vlan +dev/vale_vlan/vale_vlan_freebsd.c optional vale_vlan # compile-with "${NORMAL_C} -Wconversion -Wextra" dev/nfsmb/nfsmb.c optional nfsmb pci dev/nge/if_nge.c optional nge Added: soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c Mon May 21 19:37:09 2018 (r337244) @@ -0,0 +1,528 @@ +#include + + + +#define TAG_LENGTH 4 +#define TAG_START 12 +#define TAG_END (TAG_START + TAG_LENGTH) +#define TAG_PID 12 +#define TAG_CI 14 +#define TAG_PID_OFFSET 0 /* from start of tag */ +#define TAG_CI_OFFSET 2 /* from start of tag */ + + + +static int +tag_frame(struct nm_bdg_fwd *ft, struct netmap_vp_adapter *vpna, + uint16_t vlan_id) +{ + struct nm_bdg_fwd *ft_end = ft + ft->ft_frags - 1; + struct nm_bdg_fwd *ft_cur = NULL; + uint8_t *buf = NULL; + uint32_t buf_size; + uint16_t be_tpid; + uint16_t be_tci; /* at the moment PCP and DEI are always set to 0 */ + int n_bytes = 0; + + buf_size = NETMAP_BUF_SIZE((struct netmap_adapter *)vpna); + if (ft_end->ft_len + TAG_LENGTH > buf_size) { + D("Not enough space for the tag in the last fragment"); + return EINVAL; + } + if (ft->ft_offset + TAG_END > ft->ft_len) { + D("Header split between two nm_bdg_fwd," + "at the moment not supported"); + return EINVAL; + } + + ft_end->ft_len += TAG_LENGTH; + for (ft_cur = ft_end; ft_cur != ft-1; --ft_cur) { + uint8_t *start_addr = NULL; + uint8_t *dest_addr = NULL; + uint16_t buf_len = ft_cur->ft_len; + buf = ft_cur->ft_buf; + + if (ft_cur->ft_flags & NS_INDIRECT) { + return EINVAL; + } + if (ft_cur != ft_end) { + /* copy 4 bytes from the end of the current buffer + * to the beginning of the next buffer + */ + uint8_t *next_buf = (ft_cur+1)->ft_buf; + start_addr = buf + buf_len - TAG_LENGTH; + dest_addr = next_buf; + *(uint32_t *)dest_addr = *(uint32_t *)start_addr; + } + + start_addr = buf + ft_cur->ft_offset; + dest_addr = start_addr + TAG_LENGTH; + /* we alredy added TAG_LENGTH to ft_end->ft_len, therefore the + * last fragment case is covered without any additional check + */ + n_bytes = buf_len - TAG_LENGTH - ft_cur->ft_offset; + memmove(dest_addr, start_addr, n_bytes); + } + + /* now we need to write the tag */ + be_tpid = htobe16(0x8100); + be_tci = htobe16(vlan_id); + buf = ft->ft_buf; + *(uint16_t *)(buf + ft->ft_offset + TAG_PID) = be_tpid; + *(uint16_t *)(buf + ft->ft_offset + TAG_CI) = be_tci; + + return 0; +} + + + +static int +untag_frame(struct nm_bdg_fwd *ft, struct netmap_vp_adapter *vpna, + uint16_t *vlan_id) +{ + struct nm_bdg_fwd *ft_end = ft + ft->ft_frags - 1; + struct nm_bdg_fwd *ft_cur = NULL; + uint8_t *buf = NULL; + uint16_t be_tpid; + uint16_t be_tci; + int n_bytes = 0; + + if (ft->ft_offset + TAG_END > ft->ft_len) { + /* header split between two nm_bdg_fwd, + * at the moment not supported + */ + return EINVAL; + } + if (ft_end->ft_len < TAG_LENGTH) { + /* the last fragment empties and we need to update fragmentation + * flags etc. at the moment we don't handle this case + */ + return EINVAL; + } + + /* first we retrieve the informations we need */ + buf = ft->ft_buf; + be_tpid = *(uint16_t *)(buf + ft->ft_offset + TAG_PID); + if (be16toh(be_tpid) != 0x8100) { + D("Not an IEEE802.Q frame"); + return EINVAL; + } + be_tci = *(uint16_t *)(buf + ft->ft_offset + TAG_CI); + *vlan_id = be16toh(be_tci) & 0x0FFF; + + /* then we remove the tag */ + for (ft_cur = ft; ft_cur != ft_end+1; ++ft_cur) { + uint8_t *start_addr = NULL; + uint8_t *dest_addr = NULL; + uint16_t buf_len = ft_cur->ft_len; + buf = ft_cur->ft_buf; + + if (ft_cur->ft_flags & NS_INDIRECT) { + /* we do not support indirect userspace buffers */ + return EINVAL; + } + if (ft_cur != ft) { + /* copy 4 bytes from the start of the current buffer + * to the end of the previous buffer + */ + struct nm_bdg_fwd *prev_ft = ft_cur - 1; + uint8_t *prev_buf = prev_ft->ft_buf; + uint16_t prev_buf_len = prev_ft->ft_len; + + start_addr = buf; + dest_addr = prev_buf + prev_buf_len - TAG_LENGTH; + *(uint32_t *)dest_addr = *(uint32_t *)start_addr; + } + + dest_addr = buf + ft->ft_offset; + start_addr = dest_addr + TAG_LENGTH; + n_bytes = buf_len - TAG_LENGTH - ft->ft_offset; + memmove(dest_addr, start_addr, n_bytes); + } + + ft_end->ft_len -= TAG_LENGTH; + return 0; +} + + + +#define MAX_VLAN_ID 4096 + +struct vlan_lookup_data { + uint32_t trunk_port; + uint16_t port_to_vlan[NM_BDG_MAXPORTS]; + uint32_t vlan_to_port[MAX_VLAN_ID]; +}; + + + +static uint32_t +vlan_lookup(struct nm_bdg_fwd *ft, uint8_t *dst_ring, + struct netmap_vp_adapter *vpna, void *lookup_data) +{ + struct vlan_lookup_data *l_data = lookup_data; + uint32_t bdg_port = vpna->bdg_port; + uint32_t dest_port = NM_BDG_NOPORT; + uint16_t vlan_id = 0x000; + const char *bdg_name; + int ret = 0; + + bdg_name = netmap_bdg_name(vpna); + + if (ft->ft_flags & NS_INDIRECT) { + /* we do not handle userspace indirect buffers */ + return NM_BDG_NOPORT; + } + + if (bdg_port == l_data->trunk_port) { + ret = untag_frame(ft, vpna, &vlan_id); + if (ret) { + return NM_BDG_NOPORT; + } + + dest_port = l_data->vlan_to_port[vlan_id]; + } else { + vlan_id = l_data->port_to_vlan[bdg_port]; + ret = tag_frame(ft, vpna, vlan_id); + if (ret) { + return NM_BDG_NOPORT; + } + + dest_port = l_data->trunk_port; + } + + return dest_port; +} + + + +static struct netmap_bdg_ops vlan_ops = {vlan_lookup, NULL, NULL}; + + + +/* must be called with GLOBAL_LOCK */ +static void +initialize_lookup_data(struct vlan_lookup_data *l_data) +{ + int i; + + l_data->trunk_port = NM_BDG_NOPORT; + for (i = 0; i < NM_BDG_MAXPORTS; ++i) { + l_data->port_to_vlan[i] = 0x000; + } + for (i = 0; i < MAX_VLAN_ID; ++i) { + l_data->vlan_to_port[i] = NM_BDG_NOPORT; + } +} + + + +static int +create_vale_port(const char* name) +{ + struct nmreq_vale_newif newif; + struct nmreq_header hdr; + int ret = 0; + + D("Trying to create port '%s'", name); + + bzero(&hdr, sizeof(hdr)); + hdr.nr_version = NETMAP_API; + hdr.nr_reqtype = NETMAP_REQ_VALE_NEWIF; + strncpy(hdr.nr_name, name, sizeof(hdr.nr_name)); + + bzero(&newif, sizeof(newif)); + hdr.nr_body = (uint64_t)&newif; + + ret = nm_vi_create(&hdr); + if (ret == 0) { + vv_try_module_get(); + } else { + D("Error %d during port '%s' nm_vi_create()", ret, name); + } + + return ret; +} + + + +static int +destroy_vale_port(const char* name) +{ + int ret; + + D("Trying to destroy port '%s'", name); + ret = nm_vi_destroy(name); + if (ret == 0) { + vv_module_put(); + } else { + D("Error %d during port '%s' nm_vi_destroy()", ret, name); + } + return ret; +} + + + +static int +attach_port(const char *bdg_name, const char *port_name, void *auth_token, + uint32_t *port_index) +{ + struct nmreq_vale_attach nmr_att; + struct nmreq_header hdr; + int ret = 0; + + D("Trying to attach port '%s%s'", bdg_name, port_name); + bzero(&nmr_att, sizeof(nmr_att)); + nmr_att.reg.nr_mode = NR_REG_ALL_NIC; + + bzero(&hdr, sizeof(hdr)); + hdr.nr_version = NETMAP_API; + hdr.nr_reqtype = NETMAP_REQ_VALE_ATTACH; + hdr.nr_body = (uint64_t)&nmr_att; + snprintf(hdr.nr_name, sizeof(hdr.nr_name), "%s%s", bdg_name, port_name); + + ret = nm_bdg_ctl_attach(&hdr, auth_token); + if (ret == 0) { + vv_try_module_get(); + + } + if (port_index != NULL) { + *port_index = nmr_att.port_index; + } + return ret; +} + + + +static int +detach_port(const char *bdg_name, const char *port_name, void *auth_token, + uint32_t *port_index) +{ + struct nmreq_vale_detach nmr_det; + struct nmreq_header hdr; + int ret = 0; + + D("Trying to detach port %s%s", bdg_name, port_name); + bzero(&nmr_det, sizeof(nmr_det)); + + bzero(&hdr, sizeof(hdr)); + hdr.nr_version = NETMAP_API; + hdr.nr_reqtype = NETMAP_REQ_VALE_DETACH; + hdr.nr_body = (uint64_t)&nmr_det; + snprintf(hdr.nr_name, sizeof(hdr.nr_name), "%s%s", bdg_name, port_name); + + ret = nm_bdg_ctl_detach(&hdr, auth_token); + if (ret == 0) { + vv_module_put(); + } + if (port_index != NULL) { + *port_index = nmr_det.port_index; + } + return ret; +} + + +#define VALE_V1A "valev1A:" +#define VALE_V1B "valev1B:" +#define VALE_V2A "valev2A:" +#define VALE_V2B "valev2B:" +#define VALE_V500B "valev500B:" +#define VALE_MODA "valemodA:" +#define VALE_MODB "valemodB:" + +void *token_v1_A; +void *token_v1_B; +void *token_v2_A; +void *token_v2_B; +void *token_v500_B; +void *token_A; +void *token_B; + +struct vlan_lookup_data data_A; +struct vlan_lookup_data data_B; + + + +static void +create_ports(void) +{ + + create_vale_port("v1"); + create_vale_port("v2"); + create_vale_port("v3"); + create_vale_port("v4"); + create_vale_port("v5"); + create_vale_port("v6"); + create_vale_port("vtp"); + create_vale_port("ap1A"); + create_vale_port("ap1B"); + create_vale_port("ap2A"); + create_vale_port("ap2B"); + create_vale_port("ap500B"); +} + + + +static void +create_bridges(void) +{ + int ret; + + token_A = netmap_bdg_create(VALE_MODA, &ret); + token_B = netmap_bdg_create(VALE_MODB, &ret); + token_v1_A = netmap_bdg_create(VALE_V1A, &ret); + token_v1_B = netmap_bdg_create(VALE_V1B, &ret); + token_v2_A = netmap_bdg_create(VALE_V2A, &ret); + token_v2_B = netmap_bdg_create(VALE_V2B, &ret); + token_v500_B = netmap_bdg_create(VALE_V500B, &ret); +} + + + +static void +connect_ports(void) +{ + + attach_port(VALE_V1A, "v1", token_v1_A, NULL); + attach_port(VALE_V1A, "v2", token_v1_A, NULL); + attach_port(VALE_V1A, "ap1A", token_v1_A, NULL); + + attach_port(VALE_V2A, "v3", token_v2_A, NULL); + attach_port(VALE_V2A, "v3", token_v2_A, NULL); + attach_port(VALE_V2A, "ap2A", token_v2_A, NULL); + + attach_port(VALE_V1B, "v4", token_v1_B, NULL); + attach_port(VALE_V1B, "ap1B", token_v1_B, NULL); + + attach_port(VALE_V2B, "v5", token_v2_B, NULL); + attach_port(VALE_V2B, "ap2B", token_v2_B, NULL); + + attach_port(VALE_V500B, "v6", token_v500_B, NULL); + attach_port(VALE_V500B, "ap500B", token_v500_B, NULL); + + attach_port(VALE_MODA, "ap1A", token_A, NULL); + attach_port(VALE_MODA, "ap2A", token_A, NULL); + attach_port(VALE_MODA, "vtp", token_A, NULL); + + attach_port(VALE_MODB, "ap1B", token_B, NULL); + attach_port(VALE_MODB, "ap2B", token_B, NULL); + attach_port(VALE_MODB, "ap500B", token_B, NULL); + attach_port(VALE_MODB, "vtp", token_B, NULL); +} + + + +static void +delete_ports(void) +{ + + destroy_vale_port("v1"); + destroy_vale_port("v2"); + destroy_vale_port("v3"); + destroy_vale_port("v4"); + destroy_vale_port("v5"); + destroy_vale_port("v6"); + destroy_vale_port("vtp"); + destroy_vale_port("ap1A"); + destroy_vale_port("ap1B"); + destroy_vale_port("ap2A"); + destroy_vale_port("ap2B"); + destroy_vale_port("ap500B"); +} + + + +static void +delete_bridges(void) +{ + + netmap_bdg_destroy(VALE_MODA, &token_A); + netmap_bdg_destroy(VALE_MODB, &token_B); + netmap_bdg_destroy(VALE_V1A, &token_v1_A); + netmap_bdg_destroy(VALE_V1B, &token_v1_B); + netmap_bdg_destroy(VALE_V2A, &token_v2_A); + netmap_bdg_destroy(VALE_V2B, &token_v2_B); + netmap_bdg_destroy(VALE_V500B, &token_v500_B); +} + + + +static void +detach_ports(void) +{ + + + detach_port(VALE_MODB, "vtp", token_B, NULL); + detach_port(VALE_MODB, "ap500B", token_B, NULL); + detach_port(VALE_MODB, "ap2B", token_B, NULL); + detach_port(VALE_MODB, "ap1B", token_B, NULL); + + + detach_port(VALE_MODA, "vtp", token_A, NULL); + detach_port(VALE_MODA, "ap2A", token_A, NULL); + detach_port(VALE_MODA, "ap1A", token_A, NULL); + + + detach_port(VALE_V500B, "ap500B", token_v500_B, NULL); + detach_port(VALE_V500B, "v6", token_v500_B, NULL); + + detach_port(VALE_V2B, "ap2B", token_v2_B, NULL); + detach_port(VALE_V2B, "v5", token_v2_B, NULL); + + detach_port(VALE_V1B, "ap1B", token_v1_B, NULL); + detach_port(VALE_V1B, "v4", token_v1_B, NULL); + + detach_port(VALE_V2A, "ap2A", token_v2_A, NULL); + detach_port(VALE_V2A, "v3", token_v2_A, NULL); + detach_port(VALE_V2A, "v3", token_v2_A, NULL); + + detach_port(VALE_V1A, "ap1A", token_v1_A, NULL); + detach_port(VALE_V1A, "v2", token_v1_A, NULL); + detach_port(VALE_V1A, "v1", token_v1_A, NULL); +} + + + +static void +modify_bridges(void) +{ + + initialize_lookup_data(&data_A); + initialize_lookup_data(&data_B); + data_A.vlan_to_port[1] = 0; + data_A.vlan_to_port[2] = 1; + data_A.port_to_vlan[0] = 1; + data_A.port_to_vlan[1] = 2; + data_A.trunk_port = 2; + + data_B.vlan_to_port[1] = 0; + data_B.vlan_to_port[2] = 1; + data_B.vlan_to_port[500] = 2; + data_B.trunk_port = 3; + + netmap_bdg_regops(VALE_MODA, &vlan_ops, &data_A, token_A); + netmap_bdg_regops(VALE_MODB, &vlan_ops, &data_B, token_B); +} + + + +void +vv_create_conf(void) +{ + + create_ports(); + create_bridges(); + connect_ports(); + modify_bridges(); +} + + + +void +vv_delete_conf(void) +{ + + detach_ports(); + delete_bridges(); + delete_ports(); +} \ No newline at end of file Added: soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan_freebsd.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan_freebsd.c Mon May 21 19:37:09 2018 (r337244) @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + + +#define DEV_NAME "vale_vlan" + + + +static d_open_t vale_vlan_open; +static d_close_t vale_vlan_close; +static d_read_t vale_vlan_read; +static d_write_t vale_vlan_write; + + + +static struct cdevsw vale_vlan_cdevsw = { + .d_version = D_VERSION, + .d_open = vale_vlan_open, + .d_close = vale_vlan_close, + .d_read = vale_vlan_read, + .d_write = vale_vlan_write, + .d_name = DEV_NAME, +}; +static struct cdev *vale_vlan_cdev; +static struct sx GLOBAL_LOCK; + + + +static int +vale_vlan_open(struct cdev *dev __unused, int oflags __unused, + int devtype __unused, struct thread *td __unused) +{ + + return 0; +} + + + +static int +vale_vlan_write(struct cdev *dev __unused, struct uio *uio, int ioflag __unused) +{ + + sx_xlock(&GLOBAL_LOCK); + CURVNET_SET(TD_TO_VNET(uio->uio_td)); + vv_create_conf(); + CURVNET_RESTORE(); + sx_xunlock(&GLOBAL_LOCK); + return 0; +} + + + +static int +vale_vlan_read(struct cdev *dev __unused, struct uio *uio, int ioflag __unused) +{ + + sx_xlock(&GLOBAL_LOCK); + CURVNET_SET(TD_TO_VNET(uio->uio_td)); + vv_delete_conf(); + CURVNET_RESTORE(); + sx_xunlock(&GLOBAL_LOCK); + return 0; +} + + + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***