MFhead @ r293006
This commit is contained in:
commit
1ce5880b96
@ -4,7 +4,7 @@
|
||||
The compilation of software known as FreeBSD is distributed under the
|
||||
following terms:
|
||||
|
||||
Copyright (c) 1992-2015 The FreeBSD Project. All rights reserved.
|
||||
Copyright (c) 1992-2016 The FreeBSD Project. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
@ -105,6 +105,8 @@ OLD_FILES+=usr/lib/clang/3.7.0/include/xopintrin.h
|
||||
OLD_FILES+=usr/lib/clang/3.7.0/include/xtestintrin.h
|
||||
OLD_DIRS+=usr/lib/clang/3.7.0/include
|
||||
OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-i386.a
|
||||
OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-preinit-i386.a
|
||||
OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a
|
||||
OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-x86_64.a
|
||||
OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan_cxx-i386.a
|
||||
OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a
|
||||
|
814
bin/sh/expand.c
814
bin/sh/expand.c
File diff suppressed because it is too large
Load Diff
@ -43,12 +43,15 @@ struct arglist {
|
||||
/*
|
||||
* expandarg() flags
|
||||
*/
|
||||
#define EXP_FULL 0x1 /* perform word splitting & file globbing */
|
||||
#define EXP_SPLIT 0x1 /* perform word splitting */
|
||||
#define EXP_TILDE 0x2 /* do normal tilde expansion */
|
||||
#define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
|
||||
#define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
|
||||
#define EXP_SPLIT_LIT 0x20 /* IFS split literal text ${v+-a b c} */
|
||||
#define EXP_LIT_QUOTED 0x40 /* for EXP_SPLIT_LIT, start off quoted */
|
||||
#define EXP_GLOB 0x80 /* perform file globbing */
|
||||
|
||||
#define EXP_FULL (EXP_SPLIT | EXP_GLOB)
|
||||
|
||||
|
||||
void emptyarglist(struct arglist *);
|
||||
|
@ -7720,12 +7720,26 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
refers to is in a different object. We can't tell for
|
||||
sure yet, because something later might force the
|
||||
symbol local. */
|
||||
if (r_type != R_ARM_ABS32
|
||||
&& r_type != R_ARM_REL32
|
||||
&& r_type != R_ARM_ABS32_NOI
|
||||
&& r_type != R_ARM_REL32_NOI
|
||||
&& r_type != R_ARM_ABS12)
|
||||
h->needs_plt = 1;
|
||||
switch (r_type)
|
||||
{
|
||||
case R_ARM_ABS12:
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_ABS32_NOI:
|
||||
case R_ARM_REL32:
|
||||
case R_ARM_REL32_NOI:
|
||||
case R_ARM_MOVW_ABS_NC:
|
||||
case R_ARM_MOVT_ABS:
|
||||
case R_ARM_MOVW_PREL_NC:
|
||||
case R_ARM_MOVT_PREL:
|
||||
case R_ARM_THM_MOVW_ABS_NC:
|
||||
case R_ARM_THM_MOVT_ABS:
|
||||
case R_ARM_THM_MOVW_PREL_NC:
|
||||
case R_ARM_THM_MOVT_PREL:
|
||||
break;
|
||||
default:
|
||||
h->needs_plt = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we create a PLT entry, this relocation will reference
|
||||
it, even if it's an ABS32 relocation. */
|
||||
|
@ -1,23 +0,0 @@
|
||||
This patch adds "CC" and "clang-CC" to the list of program name aliases which
|
||||
invoke the C++ compiler.
|
||||
|
||||
Introduced here: http://svnweb.freebsd.org/changeset/base/257109
|
||||
|
||||
Index: tools/clang/tools/driver/driver.cpp
|
||||
===================================================================
|
||||
--- tools/clang/tools/driver/driver.cpp
|
||||
+++ tools/clang/tools/driver/driver.cpp
|
||||
@@ -213,11 +213,13 @@ static const DriverSuffix *FindDriverSuffix(String
|
||||
{"clang", nullptr},
|
||||
{"clang++", "--driver-mode=g++"},
|
||||
{"clang-c++", "--driver-mode=g++"},
|
||||
+ {"clang-CC", "--driver-mode=g++"},
|
||||
{"clang-cc", nullptr},
|
||||
{"clang-cpp", "--driver-mode=cpp"},
|
||||
{"clang-g++", "--driver-mode=g++"},
|
||||
{"clang-gcc", nullptr},
|
||||
{"clang-cl", "--driver-mode=cl"},
|
||||
+ {"CC", "--driver-mode=g++"},
|
||||
{"cc", nullptr},
|
||||
{"cpp", "--driver-mode=cpp"},
|
||||
{"cl", "--driver-mode=cl"},
|
@ -214,13 +214,11 @@ static const DriverSuffix *FindDriverSuffix(StringRef ProgName) {
|
||||
{"clang", nullptr},
|
||||
{"clang++", "--driver-mode=g++"},
|
||||
{"clang-c++", "--driver-mode=g++"},
|
||||
{"clang-CC", "--driver-mode=g++"},
|
||||
{"clang-cc", nullptr},
|
||||
{"clang-cpp", "--driver-mode=cpp"},
|
||||
{"clang-g++", "--driver-mode=g++"},
|
||||
{"clang-gcc", nullptr},
|
||||
{"clang-cl", "--driver-mode=cl"},
|
||||
{"CC", "--driver-mode=g++"},
|
||||
{"cc", nullptr},
|
||||
{"cpp", "--driver-mode=cpp"},
|
||||
{"cl", "--driver-mode=cl"},
|
||||
|
@ -99,16 +99,7 @@ moreglue(int n)
|
||||
FILE *p;
|
||||
size_t align;
|
||||
|
||||
/*
|
||||
* FILE has a mbstate_t variable. This variable tries to be int64_t
|
||||
* aligned through its definition. int64_t may be larger than void *,
|
||||
* which is the size traditionally used for ALIGNBYTES. So, use our own
|
||||
* rounding instead of the MI ALIGN macros. If for some reason
|
||||
* ALIGNBYTES is larger than int64_t, respect that too. There appears to
|
||||
* be no portable way to ask for FILE's alignment requirements other
|
||||
* than just knowing here.
|
||||
*/
|
||||
align = MAX(ALIGNBYTES, sizeof(int64_t));
|
||||
align = __alignof__(FILE);
|
||||
g = (struct glue *)malloc(sizeof(*g) + align + n * sizeof(FILE));
|
||||
if (g == NULL)
|
||||
return (NULL);
|
||||
|
@ -2,7 +2,7 @@
|
||||
.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
|
||||
.\"
|
||||
.\" This file is in the public domain.
|
||||
.Dd October 20, 2015
|
||||
.Dd December 29, 2015
|
||||
.Dt PTRACE 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -372,6 +372,20 @@ The flag is set for first event reported from a new child, which is
|
||||
automatically attached due to
|
||||
.Dv PT_FOLLOW_FORK
|
||||
enabled.
|
||||
.It PL_FLAG_BORN
|
||||
This flag is set for the first event reported from a new LWP when LWP
|
||||
events are enabled via
|
||||
.Dv PT_LWP_EVENTS .
|
||||
It is reported along with
|
||||
.Dv PL_FLAG_SCX
|
||||
and is always reported if LWP events are enabled.
|
||||
.It PL_FLAG_EXITED
|
||||
This flag is set for the last event reported by an exiting LWP when
|
||||
LWP events are enabled via
|
||||
.Dv PT_LWP_EVENTS .
|
||||
Note that this event is not reported when the last LWP in a process exits.
|
||||
The termination of the last thread is reported via a normal process exit
|
||||
event.
|
||||
.El
|
||||
.It pl_sigmask
|
||||
The current signal mask of the LWP
|
||||
@ -463,6 +477,29 @@ Child processes do not inherit this property.
|
||||
The traced process will set the
|
||||
.Dv PL_FLAG_FORKED
|
||||
flag upon exit from a system call that creates a new process.
|
||||
.It PT_LWP_EVENTS
|
||||
This request controls tracing of LWP creation and destruction.
|
||||
If
|
||||
.Fa data
|
||||
is non-zero,
|
||||
then LWPs will stop to report creation and destruction events.
|
||||
If
|
||||
.Fa data
|
||||
is zero,
|
||||
then LWP creation and destruction events will not be reported.
|
||||
By default, tracing is not enabled for LWP events.
|
||||
Child processes do not inherit this property.
|
||||
New LWPs will stop to report an event with
|
||||
.Dv PL_FLAG_BORN
|
||||
set before executing their first instruction.
|
||||
Exiting LWPs will stop to report an event with
|
||||
.Dv PL_FLAG_EXITED
|
||||
set before completing their termination.
|
||||
.Pp
|
||||
Note that new processes do not report an event for the creation of their
|
||||
initial thread,
|
||||
and exiting processes do not report an event for the termination of the
|
||||
last thread.
|
||||
.It PT_VM_TIMESTAMP
|
||||
This request returns the generation number or timestamp of the memory map of
|
||||
the traced process as the return value from
|
||||
|
@ -59,14 +59,18 @@ MDXFileChunk(const char *filename, char *buf, off_t ofs, off_t len)
|
||||
f = open(filename, O_RDONLY);
|
||||
if (f < 0)
|
||||
return 0;
|
||||
if (fstat(f, &stbuf) < 0)
|
||||
return 0;
|
||||
if (fstat(f, &stbuf) < 0) {
|
||||
i = -1;
|
||||
goto error;
|
||||
}
|
||||
if (ofs > stbuf.st_size)
|
||||
ofs = stbuf.st_size;
|
||||
if ((len == 0) || (len > stbuf.st_size - ofs))
|
||||
len = stbuf.st_size - ofs;
|
||||
if (lseek(f, ofs, SEEK_SET) < 0)
|
||||
return 0;
|
||||
if (lseek(f, ofs, SEEK_SET) < 0) {
|
||||
i = -1;
|
||||
goto error;
|
||||
}
|
||||
n = len;
|
||||
i = 0;
|
||||
while (n > 0) {
|
||||
@ -79,6 +83,7 @@ MDXFileChunk(const char *filename, char *buf, off_t ofs, off_t len)
|
||||
MDXUpdate(&ctx, buffer, i);
|
||||
n -= i;
|
||||
}
|
||||
error:
|
||||
e = errno;
|
||||
close(f);
|
||||
errno = e;
|
||||
|
@ -44,6 +44,12 @@ SRCS+= bcmp.c bcopy.c bzero.c ffs.c memccpy.c memchr.c memcmp.c memcpy.c \
|
||||
.if ${MACHINE_CPUARCH} == "arm"
|
||||
.PATH: ${LIBC_SRC}/arm/gen
|
||||
|
||||
# Do not generate movt/movw, because the relocation fixup for them does not
|
||||
# translate to the -Bsymbolic -pie format required by self_reloc() in loader(8).
|
||||
# Also, the fpu is not available in a standalone environment.
|
||||
CFLAGS.clang+= -mllvm -arm-use-movt=0
|
||||
CFLAGS.clang+= -mfpu=none
|
||||
|
||||
# Compiler support functions
|
||||
.PATH: ${LIBSTAND_SRC}/../../contrib/compiler-rt/lib/builtins/
|
||||
# __clzsi2 and ctzsi2 for various builtin functions
|
||||
|
@ -76,7 +76,7 @@ main(int argc, char *argv[])
|
||||
howto = RB_HALT;
|
||||
} else
|
||||
howto = 0;
|
||||
lflag = nflag = qflag = 0;
|
||||
lflag = nflag = qflag = Nflag = 0;
|
||||
while ((ch = getopt(argc, argv, "dk:lNnpqr")) != -1)
|
||||
switch(ch) {
|
||||
case 'd':
|
||||
|
@ -153,46 +153,49 @@ ASENTRY_NP(_start)
|
||||
* Build page table from scratch.
|
||||
*/
|
||||
|
||||
/* Calculate the physical address of the startup pagetable. */
|
||||
/*
|
||||
* Figure out the physical address we're loaded at by assuming this
|
||||
* entry point code is in the first L1 section and so if we clear the
|
||||
* offset bits of the pc that will give us the section-aligned load
|
||||
* address, which remains in r5 throughout all the following code.
|
||||
*/
|
||||
ldr r2, =(L1_S_OFFSET)
|
||||
bic r5, pc, r2
|
||||
|
||||
/* Find the delta between VA and PA, result stays in r0 throughout. */
|
||||
adr r0, Lpagetable
|
||||
bl translate_va_to_pa
|
||||
|
||||
/* Clear boot page table */
|
||||
mov r1, r0
|
||||
mov r2, L1_TABLE_SIZE
|
||||
mov r3,#0
|
||||
1: str r3, [r1], #4
|
||||
subs r2, #4
|
||||
bgt 1b
|
||||
|
||||
/*
|
||||
* Map PA == VA
|
||||
/*
|
||||
* First map the entire 4GB address space as VA=PA. It's mapped as
|
||||
* normal (cached) memory because it's for things like accessing the
|
||||
* parameters passed in from the bootloader, which might be at any
|
||||
* physical address, different for every platform.
|
||||
*/
|
||||
mov r1, #0
|
||||
mov r2, #0
|
||||
mov r3, #4096
|
||||
bl build_pagetables
|
||||
|
||||
/*
|
||||
* Next we do 64MiB starting at the physical load address, mapped to
|
||||
* the VA the kernel is linked for.
|
||||
*/
|
||||
/* Find the start kernels load address */
|
||||
adr r5, _start
|
||||
ldr r2, =(PTE1_OFFSET)
|
||||
bic r5, r2
|
||||
mov r1, r5
|
||||
mov r2, r5
|
||||
/* Map 64MiB, preserved over calls to build_pagetables */
|
||||
ldr r2, =(KERNVIRTADDR)
|
||||
mov r3, #64
|
||||
bl build_pagetables
|
||||
|
||||
/* Create the kernel map to jump to */
|
||||
mov r1, r5
|
||||
ldr r2, =(KERNVIRTADDR)
|
||||
bl build_pagetables
|
||||
|
||||
/* Create a device mapping for early_printf if specified. */
|
||||
#if defined(SOCDEV_PA) && defined(SOCDEV_VA)
|
||||
/* Create the custom map (1MB) used for early_printf(). */
|
||||
ldr r1, =SOCDEV_PA
|
||||
ldr r2, =SOCDEV_VA
|
||||
mov r3, #1
|
||||
bl build_pagetables
|
||||
bl build_device_pagetables
|
||||
#endif
|
||||
bl init_mmu
|
||||
|
||||
/* Switch to virtual addresses. */
|
||||
/* Transition the PC from physical to virtual addressing. */
|
||||
ldr pc, =1f
|
||||
1:
|
||||
|
||||
@ -394,6 +397,15 @@ END(reinit_mmu)
|
||||
*
|
||||
* Addresses must be 1MiB aligned
|
||||
*/
|
||||
build_device_pagetables:
|
||||
#if defined(ARM_NEW_PMAP)
|
||||
ldr r4, =PTE1_V|PTE1_A|PTE1_AP_KRW|TEX1_CLASS_0
|
||||
#elif defined(SMP)
|
||||
ldr r4, =(L1_TYPE_S|L1_S_AP(AP_KRW)|L1_SHARED)
|
||||
#else
|
||||
ldr r4, =(L1_TYPE_S|L1_S_AP(AP_KRW))
|
||||
#endif
|
||||
b 1f
|
||||
build_pagetables:
|
||||
/* Set the required page attributed */
|
||||
#if defined(ARM_NEW_PMAP)
|
||||
@ -403,18 +415,19 @@ build_pagetables:
|
||||
#else
|
||||
ldr r4, =(L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
|
||||
#endif
|
||||
1:
|
||||
orr r1, r4
|
||||
|
||||
/* Move the virtual address to the correct bit location */
|
||||
lsr r2, #(PTE1_SHIFT - 2)
|
||||
|
||||
mov r4, r3
|
||||
1:
|
||||
2:
|
||||
str r1, [r0, r2]
|
||||
add r2, r2, #4
|
||||
add r1, r1, #(PTE1_SIZE)
|
||||
adds r4, r4, #-1
|
||||
bhi 1b
|
||||
bhi 2b
|
||||
|
||||
mov pc, lr
|
||||
|
||||
|
@ -37,9 +37,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
static int ident_lock;
|
||||
|
||||
char machine[] = "arm64";
|
||||
|
||||
SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0,
|
||||
@ -56,6 +59,7 @@ SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0,
|
||||
* Aff0 - CPU number in Aff1 cluster
|
||||
*/
|
||||
uint64_t __cpu_affinity[MAXCPU];
|
||||
static u_int cpu_aff_levels;
|
||||
|
||||
struct cpu_desc {
|
||||
u_int cpu_impl;
|
||||
@ -64,9 +68,32 @@ struct cpu_desc {
|
||||
u_int cpu_revision;
|
||||
const char *cpu_impl_name;
|
||||
const char *cpu_part_name;
|
||||
|
||||
uint64_t mpidr;
|
||||
uint64_t id_aa64afr0;
|
||||
uint64_t id_aa64afr1;
|
||||
uint64_t id_aa64dfr0;
|
||||
uint64_t id_aa64dfr1;
|
||||
uint64_t id_aa64isar0;
|
||||
uint64_t id_aa64isar1;
|
||||
uint64_t id_aa64mmfr0;
|
||||
uint64_t id_aa64mmfr1;
|
||||
uint64_t id_aa64pfr0;
|
||||
uint64_t id_aa64pfr1;
|
||||
};
|
||||
|
||||
struct cpu_desc cpu_desc[MAXCPU];
|
||||
static u_int cpu_print_regs;
|
||||
#define PRINT_ID_AA64_AFR0 0x00000001
|
||||
#define PRINT_ID_AA64_AFR1 0x00000002
|
||||
#define PRINT_ID_AA64_DFR0 0x00000004
|
||||
#define PRINT_ID_AA64_DFR1 0x00000008
|
||||
#define PRINT_ID_AA64_ISAR0 0x00000010
|
||||
#define PRINT_ID_AA64_ISAR1 0x00000020
|
||||
#define PRINT_ID_AA64_MMFR0 0x00000040
|
||||
#define PRINT_ID_AA64_MMFR1 0x00000080
|
||||
#define PRINT_ID_AA64_PFR0 0x00000100
|
||||
#define PRINT_ID_AA64_PFR1 0x00000200
|
||||
|
||||
struct cpu_parts {
|
||||
u_int part_id;
|
||||
@ -124,7 +151,398 @@ const struct cpu_implementers cpu_implementers[] = {
|
||||
CPU_IMPLEMENTER_NONE,
|
||||
};
|
||||
|
||||
void identify_cpu(void);
|
||||
void
|
||||
print_cpu_features(u_int cpu)
|
||||
{
|
||||
int printed;
|
||||
|
||||
printf("CPU%3d: %s %s r%dp%d", cpu, cpu_desc[cpu].cpu_impl_name,
|
||||
cpu_desc[cpu].cpu_part_name, cpu_desc[cpu].cpu_variant,
|
||||
cpu_desc[cpu].cpu_revision);
|
||||
|
||||
printf(" affinity:");
|
||||
switch(cpu_aff_levels) {
|
||||
default:
|
||||
case 4:
|
||||
printf(" %2d", CPU_AFF3(cpu_desc[cpu].mpidr));
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
printf(" %2d", CPU_AFF2(cpu_desc[cpu].mpidr));
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
printf(" %2d", CPU_AFF1(cpu_desc[cpu].mpidr));
|
||||
/* FALLTHROUGH */
|
||||
case 1:
|
||||
case 0: /* On UP this will be zero */
|
||||
printf(" %2d", CPU_AFF0(cpu_desc[cpu].mpidr));
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if (cpu != 0 && cpu_print_regs == 0)
|
||||
return;
|
||||
|
||||
#define SEP_STR ((printed++) == 0) ? "" : ","
|
||||
|
||||
/* AArch64 Instruction Set Attribute Register 0 */
|
||||
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_ISAR0) != 0) {
|
||||
printed = 0;
|
||||
printf(" Instruction Set Attributes 0 = <");
|
||||
switch (ID_AA64ISAR0_AES(cpu_desc[cpu].id_aa64isar0)) {
|
||||
case ID_AA64ISAR0_AES_NONE:
|
||||
break;
|
||||
case ID_AA64ISAR0_AES_BASE:
|
||||
printf("%sAES", SEP_STR);
|
||||
break;
|
||||
case ID_AA64ISAR0_AES_PMULL:
|
||||
printf("%sAES+PMULL", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown AES", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64ISAR0_SHA1(cpu_desc[cpu].id_aa64isar0)) {
|
||||
case ID_AA64ISAR0_SHA1_NONE:
|
||||
break;
|
||||
case ID_AA64ISAR0_SHA1_BASE:
|
||||
printf("%sSHA1", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown SHA1", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64ISAR0_SHA2(cpu_desc[cpu].id_aa64isar0)) {
|
||||
case ID_AA64ISAR0_SHA2_NONE:
|
||||
break;
|
||||
case ID_AA64ISAR0_SHA2_BASE:
|
||||
printf("%sSHA2", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown SHA2", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64ISAR0_CRC32(cpu_desc[cpu].id_aa64isar0)) {
|
||||
case ID_AA64ISAR0_CRC32_NONE:
|
||||
break;
|
||||
case ID_AA64ISAR0_CRC32_BASE:
|
||||
printf("%sCRC32", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown CRC32", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((cpu_desc[cpu].id_aa64isar0 & ~ID_AA64ISAR0_MASK) != 0)
|
||||
printf("%s%#lx", SEP_STR,
|
||||
cpu_desc[cpu].id_aa64isar0 & ~ID_AA64ISAR0_MASK);
|
||||
|
||||
printf(">\n");
|
||||
}
|
||||
|
||||
/* AArch64 Instruction Set Attribute Register 1 */
|
||||
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_ISAR1) != 0) {
|
||||
printf(" Instruction Set Attributes 1 = <%#lx>\n",
|
||||
cpu_desc[cpu].id_aa64isar1);
|
||||
}
|
||||
|
||||
/* AArch64 Processor Feature Register 0 */
|
||||
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_PFR0) != 0) {
|
||||
printed = 0;
|
||||
printf(" Processor Features 0 = <");
|
||||
switch (ID_AA64PFR0_GIC(cpu_desc[cpu].id_aa64pfr0)) {
|
||||
case ID_AA64PFR0_GIC_CPUIF_NONE:
|
||||
break;
|
||||
case ID_AA64PFR0_GIC_CPUIF_EN:
|
||||
printf("%sGIC", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown GIC interface", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64PFR0_ADV_SIMD(cpu_desc[cpu].id_aa64pfr0)) {
|
||||
case ID_AA64PFR0_ADV_SIMD_NONE:
|
||||
break;
|
||||
case ID_AA64PFR0_ADV_SIMD_IMPL:
|
||||
printf("%sAdvSIMD", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown AdvSIMD", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64PFR0_FP(cpu_desc[cpu].id_aa64pfr0)) {
|
||||
case ID_AA64PFR0_FP_NONE:
|
||||
break;
|
||||
case ID_AA64PFR0_FP_IMPL:
|
||||
printf("%sFloat", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown Float", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64PFR0_EL3(cpu_desc[cpu].id_aa64pfr0)) {
|
||||
case ID_AA64PFR0_EL3_NONE:
|
||||
printf("%sNo EL3", SEP_STR);
|
||||
break;
|
||||
case ID_AA64PFR0_EL3_64:
|
||||
printf("%sEL3", SEP_STR);
|
||||
break;
|
||||
case ID_AA64PFR0_EL3_64_32:
|
||||
printf("%sEL3 32", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown EL3", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64PFR0_EL2(cpu_desc[cpu].id_aa64pfr0)) {
|
||||
case ID_AA64PFR0_EL2_NONE:
|
||||
printf("%sNo EL2", SEP_STR);
|
||||
break;
|
||||
case ID_AA64PFR0_EL2_64:
|
||||
printf("%sEL2", SEP_STR);
|
||||
break;
|
||||
case ID_AA64PFR0_EL2_64_32:
|
||||
printf("%sEL2 32", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown EL2", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64PFR0_EL1(cpu_desc[cpu].id_aa64pfr0)) {
|
||||
case ID_AA64PFR0_EL1_64:
|
||||
printf("%sEL1", SEP_STR);
|
||||
break;
|
||||
case ID_AA64PFR0_EL1_64_32:
|
||||
printf("%sEL1 32", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown EL1", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64PFR0_EL0(cpu_desc[cpu].id_aa64pfr0)) {
|
||||
case ID_AA64PFR0_EL0_64:
|
||||
printf("%sEL0", SEP_STR);
|
||||
break;
|
||||
case ID_AA64PFR0_EL0_64_32:
|
||||
printf("%sEL0 32", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown EL0", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((cpu_desc[cpu].id_aa64pfr0 & ~ID_AA64PFR0_MASK) != 0)
|
||||
printf("%s%#lx", SEP_STR,
|
||||
cpu_desc[cpu].id_aa64pfr0 & ~ID_AA64PFR0_MASK);
|
||||
|
||||
printf(">\n");
|
||||
}
|
||||
|
||||
/* AArch64 Processor Feature Register 1 */
|
||||
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_PFR1) != 0) {
|
||||
printf(" Processor Features 1 = <%#lx>\n",
|
||||
cpu_desc[cpu].id_aa64pfr1);
|
||||
}
|
||||
|
||||
/* AArch64 Memory Model Feature Register 0 */
|
||||
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_MMFR0) != 0) {
|
||||
printed = 0;
|
||||
printf(" Memory Model Features 0 = <");
|
||||
switch (ID_AA64MMFR0_TGRAN4(cpu_desc[cpu].id_aa64mmfr0)) {
|
||||
case ID_AA64MMFR0_TGRAN4_NONE:
|
||||
break;
|
||||
case ID_AA64MMFR0_TGRAN4_IMPL:
|
||||
printf("%s4k Granule", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown 4k Granule", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64MMFR0_TGRAN16(cpu_desc[cpu].id_aa64mmfr0)) {
|
||||
case ID_AA64MMFR0_TGRAN16_NONE:
|
||||
break;
|
||||
case ID_AA64MMFR0_TGRAN16_IMPL:
|
||||
printf("%s16k Granule", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown 16k Granule", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64MMFR0_TGRAN64(cpu_desc[cpu].id_aa64mmfr0)) {
|
||||
case ID_AA64MMFR0_TGRAN64_NONE:
|
||||
break;
|
||||
case ID_AA64MMFR0_TGRAN64_IMPL:
|
||||
printf("%s64k Granule", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown 64k Granule", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64MMFR0_BIGEND(cpu_desc[cpu].id_aa64mmfr0)) {
|
||||
case ID_AA64MMFR0_BIGEND_FIXED:
|
||||
break;
|
||||
case ID_AA64MMFR0_BIGEND_MIXED:
|
||||
printf("%sMixedEndian", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown Endian switching", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64MMFR0_BIGEND_EL0(cpu_desc[cpu].id_aa64mmfr0)) {
|
||||
case ID_AA64MMFR0_BIGEND_EL0_FIXED:
|
||||
break;
|
||||
case ID_AA64MMFR0_BIGEND_EL0_MIXED:
|
||||
printf("%sEL0 MixEndian", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown EL0 Endian switching", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64MMFR0_S_NS_MEM(cpu_desc[cpu].id_aa64mmfr0)) {
|
||||
case ID_AA64MMFR0_S_NS_MEM_NONE:
|
||||
break;
|
||||
case ID_AA64MMFR0_S_NS_MEM_DISTINCT:
|
||||
printf("%sS/NS Mem", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown S/NS Mem", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64MMFR0_ASID_BITS(cpu_desc[cpu].id_aa64mmfr0)) {
|
||||
case ID_AA64MMFR0_ASID_BITS_8:
|
||||
printf("%s8bit ASID", SEP_STR);
|
||||
break;
|
||||
case ID_AA64MMFR0_ASID_BITS_16:
|
||||
printf("%s16bit ASID", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown ASID", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64MMFR0_PA_RANGE(cpu_desc[cpu].id_aa64mmfr0)) {
|
||||
case ID_AA64MMFR0_PA_RANGE_4G:
|
||||
printf("%s4GB PA", SEP_STR);
|
||||
break;
|
||||
case ID_AA64MMFR0_PA_RANGE_64G:
|
||||
printf("%s64GB PA", SEP_STR);
|
||||
break;
|
||||
case ID_AA64MMFR0_PA_RANGE_1T:
|
||||
printf("%s1TB PA", SEP_STR);
|
||||
break;
|
||||
case ID_AA64MMFR0_PA_RANGE_4T:
|
||||
printf("%s4TB PA", SEP_STR);
|
||||
break;
|
||||
case ID_AA64MMFR0_PA_RANGE_16T:
|
||||
printf("%s16TB PA", SEP_STR);
|
||||
break;
|
||||
case ID_AA64MMFR0_PA_RANGE_256T:
|
||||
printf("%s256TB PA", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown PA Range", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((cpu_desc[cpu].id_aa64mmfr0 & ~ID_AA64MMFR0_MASK) != 0)
|
||||
printf("%s%#lx", SEP_STR,
|
||||
cpu_desc[cpu].id_aa64mmfr0 & ~ID_AA64MMFR0_MASK);
|
||||
printf(">\n");
|
||||
}
|
||||
|
||||
/* AArch64 Memory Model Feature Register 1 */
|
||||
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_MMFR1) != 0) {
|
||||
printf(" Memory Model Features 1 = <%#lx>\n",
|
||||
cpu_desc[cpu].id_aa64mmfr1);
|
||||
}
|
||||
|
||||
/* AArch64 Debug Feature Register 0 */
|
||||
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_DFR0) != 0) {
|
||||
printed = 0;
|
||||
printf(" Debug Features 0 = <");
|
||||
printf("%s%lu CTX Breakpoints", SEP_STR,
|
||||
ID_AA64DFR0_CTX_CMPS(cpu_desc[cpu].id_aa64dfr0));
|
||||
|
||||
printf("%s%lu Watchpoints", SEP_STR,
|
||||
ID_AA64DFR0_WRPS(cpu_desc[cpu].id_aa64dfr0));
|
||||
|
||||
printf("%s%lu Breakpoints", SEP_STR,
|
||||
ID_AA64DFR0_BRPS(cpu_desc[cpu].id_aa64dfr0));
|
||||
|
||||
switch (ID_AA64DFR0_PMU_VER(cpu_desc[cpu].id_aa64dfr0)) {
|
||||
case ID_AA64DFR0_PMU_VER_NONE:
|
||||
break;
|
||||
case ID_AA64DFR0_PMU_VER_3:
|
||||
printf("%sPMUv3", SEP_STR);
|
||||
break;
|
||||
case ID_AA64DFR0_PMU_VER_IMPL:
|
||||
printf("%sImplementation defined PMU", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown PMU", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64DFR0_TRACE_VER(cpu_desc[cpu].id_aa64dfr0)) {
|
||||
case ID_AA64DFR0_TRACE_VER_NONE:
|
||||
break;
|
||||
case ID_AA64DFR0_TRACE_VER_IMPL:
|
||||
printf("%sTrace", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown Trace", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64DFR0_DEBUG_VER(cpu_desc[cpu].id_aa64dfr0)) {
|
||||
case ID_AA64DFR0_DEBUG_VER_8:
|
||||
printf("%sDebug v8", SEP_STR);
|
||||
break;
|
||||
default:
|
||||
printf("%sUnknown Debug", SEP_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
if (cpu_desc[cpu].id_aa64dfr0 & ~ID_AA64DFR0_MASK)
|
||||
printf("%s%#lx", SEP_STR,
|
||||
cpu_desc[cpu].id_aa64dfr0 & ~ID_AA64DFR0_MASK);
|
||||
printf(">\n");
|
||||
}
|
||||
|
||||
/* AArch64 Memory Model Feature Register 1 */
|
||||
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_DFR1) != 0) {
|
||||
printf(" Debug Features 1 = <%#lx>\n",
|
||||
cpu_desc[cpu].id_aa64dfr1);
|
||||
}
|
||||
|
||||
/* AArch64 Auxiliary Feature Register 0 */
|
||||
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_AFR0) != 0) {
|
||||
printf(" Auxiliary Features 0 = <%#lx>\n",
|
||||
cpu_desc[cpu].id_aa64afr0);
|
||||
}
|
||||
|
||||
/* AArch64 Auxiliary Feature Register 1 */
|
||||
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_AFR1) != 0) {
|
||||
printf(" Auxiliary Features 1 = <%#lx>\n",
|
||||
cpu_desc[cpu].id_aa64afr1);
|
||||
}
|
||||
|
||||
#undef SEP_STR
|
||||
}
|
||||
|
||||
void
|
||||
identify_cpu(void)
|
||||
@ -133,7 +551,6 @@ identify_cpu(void)
|
||||
u_int impl_id;
|
||||
u_int part_id;
|
||||
u_int cpu;
|
||||
uint64_t mpidr;
|
||||
size_t i;
|
||||
const struct cpu_parts *cpu_partsp = NULL;
|
||||
|
||||
@ -171,19 +588,77 @@ identify_cpu(void)
|
||||
cpu_desc[cpu].cpu_variant = CPU_VAR(midr);
|
||||
|
||||
/* Save affinity for current CPU */
|
||||
mpidr = get_mpidr();
|
||||
CPU_AFFINITY(cpu) = mpidr & CPU_AFF_MASK;
|
||||
cpu_desc[cpu].mpidr = get_mpidr();
|
||||
CPU_AFFINITY(cpu) = cpu_desc[cpu].mpidr & CPU_AFF_MASK;
|
||||
|
||||
/* Print details for boot CPU or if we want verbose output */
|
||||
if (cpu == 0 || bootverbose) {
|
||||
printf("CPU(%d): %s %s r%dp%d\n", cpu,
|
||||
cpu_desc[cpu].cpu_impl_name,
|
||||
cpu_desc[cpu].cpu_part_name,
|
||||
cpu_desc[cpu].cpu_variant,
|
||||
cpu_desc[cpu].cpu_revision);
|
||||
cpu_desc[cpu].id_aa64dfr0 = READ_SPECIALREG(id_aa64dfr0_el1);
|
||||
cpu_desc[cpu].id_aa64dfr1 = READ_SPECIALREG(id_aa64dfr1_el1);
|
||||
cpu_desc[cpu].id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1);
|
||||
cpu_desc[cpu].id_aa64isar1 = READ_SPECIALREG(id_aa64isar1_el1);
|
||||
cpu_desc[cpu].id_aa64mmfr0 = READ_SPECIALREG(id_aa64mmfr0_el1);
|
||||
cpu_desc[cpu].id_aa64mmfr1 = READ_SPECIALREG(id_aa64mmfr1_el1);
|
||||
cpu_desc[cpu].id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1);
|
||||
cpu_desc[cpu].id_aa64pfr1 = READ_SPECIALREG(id_aa64pfr1_el1);
|
||||
|
||||
if (cpu != 0) {
|
||||
/*
|
||||
* This code must run on one cpu at a time, but we are
|
||||
* not scheduling on the current core so implement a
|
||||
* simple spinlock.
|
||||
*/
|
||||
while (atomic_cmpset_acq_int(&ident_lock, 0, 1) == 0)
|
||||
__asm __volatile("wfe" ::: "memory");
|
||||
|
||||
switch (cpu_aff_levels) {
|
||||
case 0:
|
||||
if (CPU_AFF0(cpu_desc[cpu].mpidr) !=
|
||||
CPU_AFF0(cpu_desc[0].mpidr))
|
||||
cpu_aff_levels = 1;
|
||||
/* FALLTHROUGH */
|
||||
case 1:
|
||||
if (CPU_AFF1(cpu_desc[cpu].mpidr) !=
|
||||
CPU_AFF1(cpu_desc[0].mpidr))
|
||||
cpu_aff_levels = 2;
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
if (CPU_AFF2(cpu_desc[cpu].mpidr) !=
|
||||
CPU_AFF2(cpu_desc[0].mpidr))
|
||||
cpu_aff_levels = 3;
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
if (CPU_AFF3(cpu_desc[cpu].mpidr) !=
|
||||
CPU_AFF3(cpu_desc[0].mpidr))
|
||||
cpu_aff_levels = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cpu_desc[cpu].id_aa64afr0 != cpu_desc[0].id_aa64afr0)
|
||||
cpu_print_regs |= PRINT_ID_AA64_AFR0;
|
||||
if (cpu_desc[cpu].id_aa64afr1 != cpu_desc[0].id_aa64afr1)
|
||||
cpu_print_regs |= PRINT_ID_AA64_AFR1;
|
||||
|
||||
if (cpu_desc[cpu].id_aa64dfr0 != cpu_desc[0].id_aa64dfr0)
|
||||
cpu_print_regs |= PRINT_ID_AA64_DFR0;
|
||||
if (cpu_desc[cpu].id_aa64dfr1 != cpu_desc[0].id_aa64dfr1)
|
||||
cpu_print_regs |= PRINT_ID_AA64_DFR1;
|
||||
|
||||
if (cpu_desc[cpu].id_aa64isar0 != cpu_desc[0].id_aa64isar0)
|
||||
cpu_print_regs |= PRINT_ID_AA64_ISAR0;
|
||||
if (cpu_desc[cpu].id_aa64isar1 != cpu_desc[0].id_aa64isar1)
|
||||
cpu_print_regs |= PRINT_ID_AA64_ISAR1;
|
||||
|
||||
if (cpu_desc[cpu].id_aa64mmfr0 != cpu_desc[0].id_aa64mmfr0)
|
||||
cpu_print_regs |= PRINT_ID_AA64_MMFR0;
|
||||
if (cpu_desc[cpu].id_aa64mmfr1 != cpu_desc[0].id_aa64mmfr1)
|
||||
cpu_print_regs |= PRINT_ID_AA64_MMFR1;
|
||||
|
||||
if (cpu_desc[cpu].id_aa64pfr0 != cpu_desc[0].id_aa64pfr0)
|
||||
cpu_print_regs |= PRINT_ID_AA64_PFR0;
|
||||
if (cpu_desc[cpu].id_aa64pfr1 != cpu_desc[0].id_aa64pfr1)
|
||||
cpu_print_regs |= PRINT_ID_AA64_PFR1;
|
||||
|
||||
/* Wake up the other CPUs */
|
||||
atomic_store_rel_int(&ident_lock, 0);
|
||||
__asm __volatile("sev" ::: "memory");
|
||||
}
|
||||
|
||||
if (bootverbose)
|
||||
printf("CPU%u affinity: %u.%u.%u.%u\n", 0, CPU_AFF0(mpidr),
|
||||
CPU_AFF1(mpidr), CPU_AFF2(mpidr), CPU_AFF3(mpidr));
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ arm64_cpu_attach(device_t dev)
|
||||
static void
|
||||
release_aps(void *dummy __unused)
|
||||
{
|
||||
int i;
|
||||
int cpu, i;
|
||||
|
||||
/* Setup the IPI handler */
|
||||
for (i = 0; i < COUNT_IPI; i++)
|
||||
@ -188,8 +188,14 @@ release_aps(void *dummy __unused)
|
||||
printf("Release APs\n");
|
||||
|
||||
for (i = 0; i < 2000; i++) {
|
||||
if (smp_started)
|
||||
if (smp_started) {
|
||||
for (cpu = 0; cpu <= mp_maxid; cpu++) {
|
||||
if (CPU_ABSENT(cpu))
|
||||
continue;
|
||||
print_cpu_features(cpu);
|
||||
}
|
||||
return;
|
||||
}
|
||||
DELAY(1000);
|
||||
}
|
||||
|
||||
|
@ -121,19 +121,147 @@
|
||||
/* ICC_SRE_EL2 */
|
||||
#define ICC_SRE_EL2_EN (1U << 3)
|
||||
|
||||
/* ID_AA64DFR0_EL1 */
|
||||
#define ID_AA64DFR0_MASK 0xf0f0ffff
|
||||
#define ID_AA64DFR0_DEBUG_VER_SHIFT 0
|
||||
#define ID_AA64DFR0_DEBUG_VER_MASK (0xf << ID_AA64DFR0_DEBUG_VER_SHIFT)
|
||||
#define ID_AA64DFR0_DEBUG_VER(x) ((x) & ID_AA64DFR0_DEBUG_VER_MASK)
|
||||
#define ID_AA64DFR0_DEBUG_VER_8 (0x6 << ID_AA64DFR0_DEBUG_VER_SHIFT)
|
||||
#define ID_AA64DFR0_TRACE_VER_SHIFT 4
|
||||
#define ID_AA64DFR0_TRACE_VER_MASK (0xf << ID_AA64DFR0_TRACE_VER_SHIFT)
|
||||
#define ID_AA64DFR0_TRACE_VER(x) ((x) & ID_AA64DFR0_TRACE_VER_MASK)
|
||||
#define ID_AA64DFR0_TRACE_VER_NONE (0x0 << ID_AA64DFR0_TRACE_VER_SHIFT)
|
||||
#define ID_AA64DFR0_TRACE_VER_IMPL (0x1 << ID_AA64DFR0_TRACE_VER_SHIFT)
|
||||
#define ID_AA64DFR0_PMU_VER_SHIFT 8
|
||||
#define ID_AA64DFR0_PMU_VER_MASK (0xf << ID_AA64DFR0_PMU_VER_SHIFT)
|
||||
#define ID_AA64DFR0_PMU_VER(x) ((x) & ID_AA64DFR0_PMU_VER_MASK)
|
||||
#define ID_AA64DFR0_PMU_VER_NONE (0x0 << ID_AA64DFR0_PMU_VER_SHIFT)
|
||||
#define ID_AA64DFR0_PMU_VER_3 (0x1 << ID_AA64DFR0_PMU_VER_SHIFT)
|
||||
#define ID_AA64DFR0_PMU_VER_IMPL (0xf << ID_AA64DFR0_PMU_VER_SHIFT)
|
||||
#define ID_AA64DFR0_BRPS_SHIFT 12
|
||||
#define ID_AA64DFR0_BRPS_MASK (0xf << ID_AA64DFR0_BRPS_SHIFT)
|
||||
#define ID_AA64DFR0_BRPS(x) \
|
||||
((((x) >> ID_AA64DFR0_BRPS_SHIFT) & 0xf) + 1)
|
||||
#define ID_AA64DFR0_WRPS_SHIFT 20
|
||||
#define ID_AA64DFR0_WRPS_MASK (0xf << ID_AA64DFR0_WRPS_SHIFT)
|
||||
#define ID_AA64DFR0_WRPS(x) \
|
||||
((((x) >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) + 1)
|
||||
#define ID_AA64DFR0_CTX_CMPS_SHIFT 28
|
||||
#define ID_AA64DFR0_CTX_CMPS_MASK (0xf << ID_AA64DFR0_CTX_CMPS_SHIFT)
|
||||
#define ID_AA64DFR0_CTX_CMPS(x) \
|
||||
((((x) >> ID_AA64DFR0_CTX_CMPS_SHIFT) & 0xf) + 1)
|
||||
|
||||
/* ID_AA64ISAR0_EL1 */
|
||||
#define ID_AA64ISAR0_MASK 0x000ffff0
|
||||
#define ID_AA64ISAR0_AES_SHIFT 4
|
||||
#define ID_AA64ISAR0_AES_MASK (0xf << ID_AA64ISAR0_AES_SHIFT)
|
||||
#define ID_AA64ISAR0_AES(x) ((x) & ID_AA64ISAR0_AES_MASK)
|
||||
#define ID_AA64ISAR0_AES_NONE (0x0 << ID_AA64ISAR0_AES_SHIFT)
|
||||
#define ID_AA64ISAR0_AES_BASE (0x1 << ID_AA64ISAR0_AES_SHIFT)
|
||||
#define ID_AA64ISAR0_AES_PMULL (0x2 << ID_AA64ISAR0_AES_SHIFT)
|
||||
#define ID_AA64ISAR0_SHA1_SHIFT 8
|
||||
#define ID_AA64ISAR0_SHA1_MASK (0xf << ID_AA64ISAR0_SHA1_SHIFT)
|
||||
#define ID_AA64ISAR0_SHA1(x) ((x) & ID_AA64ISAR0_SHA1_MASK)
|
||||
#define ID_AA64ISAR0_SHA1_NONE (0x0 << ID_AA64ISAR0_SHA1_SHIFT)
|
||||
#define ID_AA64ISAR0_SHA1_BASE (0x1 << ID_AA64ISAR0_SHA1_SHIFT)
|
||||
#define ID_AA64ISAR0_SHA2_SHIFT 12
|
||||
#define ID_AA64ISAR0_SHA2_MASK (0xf << ID_AA64ISAR0_SHA2_SHIFT)
|
||||
#define ID_AA64ISAR0_SHA2(x) ((x) & ID_AA64ISAR0_SHA2_MASK)
|
||||
#define ID_AA64ISAR0_SHA2_NONE (0x0 << ID_AA64ISAR0_SHA2_SHIFT)
|
||||
#define ID_AA64ISAR0_SHA2_BASE (0x1 << ID_AA64ISAR0_SHA2_SHIFT)
|
||||
#define ID_AA64ISAR0_CRC32_SHIFT 16
|
||||
#define ID_AA64ISAR0_CRC32_MASK (0xf << ID_AA64ISAR0_CRC32_SHIFT)
|
||||
#define ID_AA64ISAR0_CRC32(x) ((x) & ID_AA64ISAR0_CRC32_MASK)
|
||||
#define ID_AA64ISAR0_CRC32_NONE (0x0 << ID_AA64ISAR0_CRC32_SHIFT)
|
||||
#define ID_AA64ISAR0_CRC32_BASE (0x1 << ID_AA64ISAR0_CRC32_SHIFT)
|
||||
|
||||
/* ID_AA64MMFR0_EL1 */
|
||||
#define ID_AA64MMFR0_MASK 0xffffffff
|
||||
#define ID_AA64MMFR0_PA_RANGE_SHIFT 0
|
||||
#define ID_AA64MMFR0_PA_RANGE_MASK (0xf << ID_AA64MMFR0_PA_RANGE_SHIFT)
|
||||
#define ID_AA64MMFR0_PA_RANGE(x) ((x) & ID_AA64MMFR0_PA_RANGE_MASK)
|
||||
#define ID_AA64MMFR0_PA_RANGE_4G (0x0 << ID_AA64MMFR0_PA_RANGE_SHIFT)
|
||||
#define ID_AA64MMFR0_PA_RANGE_64G (0x1 << ID_AA64MMFR0_PA_RANGE_SHIFT)
|
||||
#define ID_AA64MMFR0_PA_RANGE_1T (0x2 << ID_AA64MMFR0_PA_RANGE_SHIFT)
|
||||
#define ID_AA64MMFR0_PA_RANGE_4T (0x3 << ID_AA64MMFR0_PA_RANGE_SHIFT)
|
||||
#define ID_AA64MMFR0_PA_RANGE_16T (0x4 << ID_AA64MMFR0_PA_RANGE_SHIFT)
|
||||
#define ID_AA64MMFR0_PA_RANGE_256T (0x5 << ID_AA64MMFR0_PA_RANGE_SHIFT)
|
||||
#define ID_AA64MMFR0_ASID_BITS_SHIFT 4
|
||||
#define ID_AA64MMFR0_ASID_BITS_MASK (0xf << ID_AA64MMFR0_ASID_BITS_SHIFT)
|
||||
#define ID_AA64MMFR0_ASID_BITS(x) ((x) & ID_AA64MMFR0_ASID_BITS_MASK)
|
||||
#define ID_AA64MMFR0_ASID_BITS_8 (0x0 << ID_AA64MMFR0_ASID_BITS_SHIFT)
|
||||
#define ID_AA64MMFR0_ASID_BITS_16 (0x2 << ID_AA64MMFR0_ASID_BITS_SHIFT)
|
||||
#define ID_AA64MMFR0_BIGEND_SHIFT 8
|
||||
#define ID_AA64MMFR0_BIGEND_MASK (0xf << ID_AA64MMFR0_BIGEND_SHIFT)
|
||||
#define ID_AA64MMFR0_BIGEND(x) ((x) & ID_AA64MMFR0_BIGEND_MASK)
|
||||
#define ID_AA64MMFR0_BIGEND_FIXED (0x0 << ID_AA64MMFR0_BIGEND_SHIFT)
|
||||
#define ID_AA64MMFR0_BIGEND_MIXED (0x1 << ID_AA64MMFR0_BIGEND_SHIFT)
|
||||
#define ID_AA64MMFR0_S_NS_MEM_SHIFT 12
|
||||
#define ID_AA64MMFR0_S_NS_MEM_MASK (0xf << ID_AA64MMFR0_S_NS_MEM_SHIFT)
|
||||
#define ID_AA64MMFR0_S_NS_MEM(x) ((x) & ID_AA64MMFR0_S_NS_MEM_MASK)
|
||||
#define ID_AA64MMFR0_S_NS_MEM_NONE (0x0 << ID_AA64MMFR0_S_NS_MEM_SHIFT)
|
||||
#define ID_AA64MMFR0_S_NS_MEM_DISTINCT (0x1 << ID_AA64MMFR0_S_NS_MEM_SHIFT)
|
||||
#define ID_AA64MMFR0_BIGEND_EL0_SHIFT 16
|
||||
#define ID_AA64MMFR0_BIGEND_EL0_MASK (0xf << ID_AA64MMFR0_BIGEND_EL0_SHIFT)
|
||||
#define ID_AA64MMFR0_BIGEND_EL0(x) ((x) & ID_AA64MMFR0_BIGEND_EL0_MASK)
|
||||
#define ID_AA64MMFR0_BIGEND_EL0_FIXED (0x0 << ID_AA64MMFR0_BIGEND_EL0_SHIFT)
|
||||
#define ID_AA64MMFR0_BIGEND_EL0_MIXED (0x1 << ID_AA64MMFR0_BIGEND_EL0_SHIFT)
|
||||
#define ID_AA64MMFR0_TGRAN16_SHIFT 20
|
||||
#define ID_AA64MMFR0_TGRAN16_MASK (0xf << ID_AA64MMFR0_TGRAN16_SHIFT)
|
||||
#define ID_AA64MMFR0_TGRAN16(x) ((x) & ID_AA64MMFR0_TGRAN16_MASK)
|
||||
#define ID_AA64MMFR0_TGRAN16_NONE (0x0 << ID_AA64MMFR0_TGRAN16_SHIFT)
|
||||
#define ID_AA64MMFR0_TGRAN16_IMPL (0x1 << ID_AA64MMFR0_TGRAN16_SHIFT)
|
||||
#define ID_AA64MMFR0_TGRAN64_SHIFT 24
|
||||
#define ID_AA64MMFR0_TGRAN64_MASK (0xf << ID_AA64MMFR0_TGRAN64_SHIFT)
|
||||
#define ID_AA64MMFR0_TGRAN64(x) ((x) & ID_AA64MMFR0_TGRAN64_MASK)
|
||||
#define ID_AA64MMFR0_TGRAN64_IMPL (0x0 << ID_AA64MMFR0_TGRAN64_SHIFT)
|
||||
#define ID_AA64MMFR0_TGRAN64_NONE (0xf << ID_AA64MMFR0_TGRAN64_SHIFT)
|
||||
#define ID_AA64MMFR0_TGRAN4_SHIFT 28
|
||||
#define ID_AA64MMFR0_TGRAN4_MASK (0xf << ID_AA64MMFR0_TGRAN4_SHIFT)
|
||||
#define ID_AA64MMFR0_TGRAN4(x) ((x) & ID_AA64MMFR0_TGRAN4_MASK)
|
||||
#define ID_AA64MMFR0_TGRAN4_IMPL (0x0 << ID_AA64MMFR0_TGRAN4_SHIFT)
|
||||
#define ID_AA64MMFR0_TGRAN4_NONE (0xf << ID_AA64MMFR0_TGRAN4_SHIFT)
|
||||
|
||||
/* ID_AA64PFR0_EL1 */
|
||||
#define ID_AA64PFR0_EL0_MASK (0xf << 0)
|
||||
#define ID_AA64PFR0_EL1_MASK (0xf << 4)
|
||||
#define ID_AA64PFR0_EL2_MASK (0xf << 8)
|
||||
#define ID_AA64PFR0_EL3_MASK (0xf << 12)
|
||||
#define ID_AA64PFR0_FP_MASK (0xf << 16)
|
||||
#define ID_AA64PFR0_FP_IMPL (0x0 << 16) /* Floating-point implemented */
|
||||
#define ID_AA64PFR0_FP_NONE (0xf << 16) /* Floating-point not implemented */
|
||||
#define ID_AA64PFR0_ADV_SIMD_MASK (0xf << 20)
|
||||
#define ID_AA64PFR0_GIC_SHIFT (24)
|
||||
#define ID_AA64PFR0_GIC_BITS (0x4) /* Number of bits in GIC field */
|
||||
#define ID_AA64PFR0_GIC_MASK (0xf << ID_AA64PFR0_GIC_SHIFT)
|
||||
#define ID_AA64PFR0_GIC_CPUIF_EN (0x1 << ID_AA64PFR0_GIC_SHIFT)
|
||||
#define ID_AA64PFR0_MASK 0x0fffffff
|
||||
#define ID_AA64PFR0_EL0_SHIFT 0
|
||||
#define ID_AA64PFR0_EL0_MASK (0xf << ID_AA64PFR0_EL0_SHIFT)
|
||||
#define ID_AA64PFR0_EL0(x) ((x) & ID_AA64PFR0_EL0_MASK)
|
||||
#define ID_AA64PFR0_EL0_64 (1 << ID_AA64PFR0_EL0_SHIFT)
|
||||
#define ID_AA64PFR0_EL0_64_32 (2 << ID_AA64PFR0_EL0_SHIFT)
|
||||
#define ID_AA64PFR0_EL1_SHIFT 4
|
||||
#define ID_AA64PFR0_EL1_MASK (0xf << ID_AA64PFR0_EL1_SHIFT)
|
||||
#define ID_AA64PFR0_EL1(x) ((x) & ID_AA64PFR0_EL1_MASK)
|
||||
#define ID_AA64PFR0_EL1_64 (1 << ID_AA64PFR0_EL1_SHIFT)
|
||||
#define ID_AA64PFR0_EL1_64_32 (2 << ID_AA64PFR0_EL1_SHIFT)
|
||||
#define ID_AA64PFR0_EL2_SHIFT 8
|
||||
#define ID_AA64PFR0_EL2_MASK (0xf << ID_AA64PFR0_EL2_SHIFT)
|
||||
#define ID_AA64PFR0_EL2(x) ((x) & ID_AA64PFR0_EL2_MASK)
|
||||
#define ID_AA64PFR0_EL2_NONE (0 << ID_AA64PFR0_EL2_SHIFT)
|
||||
#define ID_AA64PFR0_EL2_64 (1 << ID_AA64PFR0_EL2_SHIFT)
|
||||
#define ID_AA64PFR0_EL2_64_32 (2 << ID_AA64PFR0_EL2_SHIFT)
|
||||
#define ID_AA64PFR0_EL3_SHIFT 12
|
||||
#define ID_AA64PFR0_EL3_MASK (0xf << ID_AA64PFR0_EL3_SHIFT)
|
||||
#define ID_AA64PFR0_EL3(x) ((x) & ID_AA64PFR0_EL3_MASK)
|
||||
#define ID_AA64PFR0_EL3_NONE (0 << ID_AA64PFR0_EL3_SHIFT)
|
||||
#define ID_AA64PFR0_EL3_64 (1 << ID_AA64PFR0_EL3_SHIFT)
|
||||
#define ID_AA64PFR0_EL3_64_32 (2 << ID_AA64PFR0_EL3_SHIFT)
|
||||
#define ID_AA64PFR0_FP_SHIFT 16
|
||||
#define ID_AA64PFR0_FP_MASK (0xf << ID_AA64PFR0_FP_SHIFT)
|
||||
#define ID_AA64PFR0_FP(x) ((x) & ID_AA64PFR0_FP_MASK)
|
||||
#define ID_AA64PFR0_FP_IMPL (0x0 << ID_AA64PFR0_FP_SHIFT)
|
||||
#define ID_AA64PFR0_FP_NONE (0xf << ID_AA64PFR0_FP_SHIFT)
|
||||
#define ID_AA64PFR0_ADV_SIMD_SHIFT 20
|
||||
#define ID_AA64PFR0_ADV_SIMD_MASK (0xf << ID_AA64PFR0_ADV_SIMD_SHIFT)
|
||||
#define ID_AA64PFR0_ADV_SIMD(x) ((x) & ID_AA64PFR0_ADV_SIMD_MASK)
|
||||
#define ID_AA64PFR0_ADV_SIMD_IMPL (0x0 << ID_AA64PFR0_ADV_SIMD_SHIFT)
|
||||
#define ID_AA64PFR0_ADV_SIMD_NONE (0xf << ID_AA64PFR0_ADV_SIMD_SHIFT)
|
||||
#define ID_AA64PFR0_GIC_BITS 0x4 /* Number of bits in GIC field */
|
||||
#define ID_AA64PFR0_GIC_SHIFT 24
|
||||
#define ID_AA64PFR0_GIC_MASK (0xf << ID_AA64PFR0_GIC_SHIFT)
|
||||
#define ID_AA64PFR0_GIC(x) ((x) & ID_AA64PFR0_GIC_MASK)
|
||||
#define ID_AA64PFR0_GIC_CPUIF_NONE (0x0 << ID_AA64PFR0_GIC_SHIFT)
|
||||
#define ID_AA64PFR0_GIC_CPUIF_EN (0x1 << ID_AA64PFR0_GIC_SHIFT)
|
||||
|
||||
/* MAIR_EL1 - Memory Attribute Indirection Register */
|
||||
#define MAIR_ATTR_MASK(idx) (0xff << ((n)* 8))
|
||||
|
@ -145,6 +145,7 @@ void cpu_halt(void) __dead2;
|
||||
void cpu_reset(void) __dead2;
|
||||
void fork_trampoline(void);
|
||||
void identify_cpu(void);
|
||||
void print_cpu_features(u_int);
|
||||
void swi_vm(void *v);
|
||||
|
||||
#define CPU_AFFINITY(cpu) __cpu_affinity[(cpu)]
|
||||
|
@ -90,6 +90,7 @@ ram_blacklist_type="ram_blacklist" # Required for the kernel to find
|
||||
#password="" # Prevent changes to boot options
|
||||
#bootlock_password="" # Prevent booting (see check-password.4th(8))
|
||||
#geom_eli_passphrase_prompt="NO" # Prompt for geli(8) passphrase to mount root
|
||||
bootenv_autolist="YES" # Auto populate the list of ZFS Boot Environments
|
||||
#beastie_disable="NO" # Turn the beastie boot menu on and off
|
||||
#kernels="kernel kernel.old" # Kernels to display in the boot menu
|
||||
#loader_logo="orbbw" # Desired logo: orbbw, orb, fbsdbw, beastiebw, beastie, none
|
||||
|
@ -351,4 +351,68 @@ also menu-namespace also menu-command-helpers
|
||||
2 goto_menu
|
||||
;
|
||||
|
||||
\
|
||||
\ Set boot environment defaults
|
||||
\
|
||||
|
||||
: init_bootenv ( -- )
|
||||
s" set menu_caption[1]=${bemenu_current}${vfs.root.mountfrom}" evaluate
|
||||
s" set ansi_caption[1]=${beansi_current}${vfs.root.mountfrom}" evaluate
|
||||
s" set menu_caption[2]=${bemenu_bootfs}${zfs_be_active}" evaluate
|
||||
s" set ansi_caption[2]=${beansi_bootfs}${zfs_be_active}" evaluate
|
||||
s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
|
||||
s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
|
||||
;
|
||||
|
||||
\
|
||||
\ Redraw the entire screen. A long BE name can corrupt the menu
|
||||
\
|
||||
|
||||
: be_draw_screen
|
||||
clear \ Clear the screen (in screen.4th)
|
||||
print_version \ print version string (bottom-right; see version.4th)
|
||||
draw-beastie \ Draw FreeBSD logo at right (in beastie.4th)
|
||||
draw-brand \ Draw brand.4th logo at top (in brand.4th)
|
||||
menu-init \ Initialize menu and draw bounding box (in menu.4th)
|
||||
;
|
||||
|
||||
\
|
||||
\ Select a boot environment
|
||||
\
|
||||
|
||||
: set_bootenv ( N -- N TRUE )
|
||||
dup s" set vfs.root.mountfrom=${bootenv_root[E]}" 38 +c! evaluate
|
||||
s" set currdev=${vfs.root.mountfrom}:" evaluate
|
||||
s" unload" evaluate
|
||||
free-module-options
|
||||
s" /boot/defaults/loader.conf" read-conf
|
||||
s" /boot/loader.conf" read-conf
|
||||
s" /boot/loader.conf.local" read-conf
|
||||
init_bootenv
|
||||
be_draw_screen
|
||||
menu-redraw
|
||||
TRUE
|
||||
;
|
||||
|
||||
\
|
||||
\ Switch to the next page of boot environments
|
||||
\
|
||||
|
||||
: set_be_page ( N -- N TRUE )
|
||||
s" zfs_be_currpage" getenv dup -1 = if
|
||||
drop s" 1"
|
||||
else
|
||||
0 s>d 2swap
|
||||
>number ( ud caddr/u -- ud' caddr'/u' ) \ convert string to numbers
|
||||
2drop \ drop the string
|
||||
1 um/mod ( ud u1 -- u2 u3 ) \ convert double ud' to single u3' and remainder u2
|
||||
swap drop ( ud2 u3 -- u3 ) \ drop the remainder u2
|
||||
1+ \ increment the page number
|
||||
s>d <# #s #> \ convert back to a string
|
||||
then
|
||||
s" zfs_be_currpage" setenv
|
||||
s" reloadbe" evaluate
|
||||
3 goto_menu
|
||||
;
|
||||
|
||||
only forth definitions
|
||||
|
@ -68,6 +68,13 @@ set mainmenu_command[6]="2 goto_menu"
|
||||
set mainmenu_keycode[6]=111
|
||||
set mainansi_caption[6]="Configure Boot ^[1mO^[mptions..."
|
||||
|
||||
s" currdev" getenv dup 0> [if] drop 4 s" zfs:" compare 0= [if]
|
||||
set mainmenu_caption[7]="Select Boot [E]nvironment..."
|
||||
set mainmenu_command[7]="3 goto_menu"
|
||||
set mainmenu_keycode[7]=101
|
||||
set mainansi_caption[7]="Select Boot ^[1mE^[37mnvironment..."
|
||||
[then] [else] drop [then]
|
||||
|
||||
\
|
||||
\ BOOT OPTIONS MENU
|
||||
\
|
||||
@ -119,6 +126,37 @@ set optionsmenu_keycode[6]=118
|
||||
set optionsansi_caption[6]="^[1mV^[merbose..... ^[34;1mOff^[m"
|
||||
set optionstoggled_ansi[6]="^[1mV^[merbose..... ^[32;7mOn^[m"
|
||||
|
||||
\
|
||||
\ BOOT ENVIRONMENT MENU
|
||||
\
|
||||
|
||||
set menuset_name3="bootenv"
|
||||
|
||||
set bemenu_current="Active: "
|
||||
set beansi_current="^[1m${bemenu_current}^[m"
|
||||
set bemenu_bootfs="bootfs: "
|
||||
set beansi_bootfs="^[1m${bemenu_bootfs}^[m"
|
||||
set bemenu_page="[P]age: "
|
||||
set beansi_page="^[1mP^[mage: "
|
||||
set bemenu_pageof=" of "
|
||||
set beansi_pageof="${bemenu_pageof}"
|
||||
set zfs_be_currpage=1
|
||||
|
||||
set bootenvmenu_init="init_bootenv"
|
||||
|
||||
set bootenvmenu_command[1]="be_draw_screen 1 goto_menu"
|
||||
set bootenvmenu_keycode[1]=8
|
||||
|
||||
set bootenvmenu_command[2]="set_bootenv"
|
||||
set bootenvmenu_keycode[2]=97
|
||||
set bootenv_root[2]="${zfs_be_active}"
|
||||
|
||||
set bootenvmenu_command[3]="set_be_page"
|
||||
set bootenvmenu_keycode[3]=112
|
||||
|
||||
set bootenvmenu_options=4
|
||||
set bootenvmenu_optionstext="Boot Environments:"
|
||||
|
||||
\ Enable automatic booting (add ``autoboot_delay=N'' to loader.conf(5) to
|
||||
\ customize the timeout; default is 10-seconds)
|
||||
\
|
||||
@ -128,6 +166,21 @@ set menu_timeout_command="boot"
|
||||
\
|
||||
try-include /boot/menu.rc.local
|
||||
|
||||
\ Initialize boot environment variables
|
||||
\
|
||||
s" reloadbe" sfind ( xt|0 bool ) [if]
|
||||
s" bootenv_autolist" getenv dup -1 = [if]
|
||||
drop s" execute" evaluate \ Use evaluate to avoid passing
|
||||
\ reloadbe an optional parameter
|
||||
[else]
|
||||
s" YES" compare-insensitive 0= [if]
|
||||
s" execute" evaluate
|
||||
[then]
|
||||
[then]
|
||||
[else]
|
||||
drop ( xt=0 )
|
||||
[then]
|
||||
|
||||
\ Display the main menu (see `menu.4th')
|
||||
set menuset_initial=1
|
||||
menuset-loadinitial
|
||||
|
@ -684,7 +684,7 @@ only forth also support-functions also file-processing definitions
|
||||
s" loader_conf_files" getenv conf_files string=
|
||||
;
|
||||
|
||||
: set_nextboot_conf \ XXX maybe do as set_conf_files ?
|
||||
: set_nextboot_conf
|
||||
value_buffer strget unquote nextboot_conf_file string=
|
||||
;
|
||||
|
||||
@ -833,7 +833,7 @@ get-current ( -- wid ) previous definitions >search ( wid -- )
|
||||
repeat
|
||||
;
|
||||
|
||||
: peek_file
|
||||
: peek_file ( addr len -- )
|
||||
0 to end_of_file?
|
||||
reset_line_reading
|
||||
O_RDONLY fopen fd !
|
||||
@ -844,6 +844,7 @@ get-current ( -- wid ) previous definitions >search ( wid -- )
|
||||
['] process_assignment catch
|
||||
['] free_buffers catch
|
||||
fd @ fclose
|
||||
swap throw throw
|
||||
;
|
||||
|
||||
only forth also support-functions definitions
|
||||
@ -851,7 +852,6 @@ only forth also support-functions definitions
|
||||
\ Interface to loading conf files
|
||||
|
||||
: load_conf ( addr len -- )
|
||||
\ ." ----- Trying conf " 2dup type cr \ debugging
|
||||
0 to end_of_file?
|
||||
reset_line_reading
|
||||
O_RDONLY fopen fd !
|
||||
@ -930,6 +930,30 @@ only forth definitions also support-functions
|
||||
repeat
|
||||
;
|
||||
|
||||
: free-one-module { addr -- addr }
|
||||
addr module.name strfree
|
||||
addr module.loadname strfree
|
||||
addr module.type strfree
|
||||
addr module.args strfree
|
||||
addr module.beforeload strfree
|
||||
addr module.afterload strfree
|
||||
addr module.loaderror strfree
|
||||
addr
|
||||
;
|
||||
|
||||
: free-module-options
|
||||
module_options @
|
||||
begin
|
||||
?dup
|
||||
while
|
||||
free-one-module
|
||||
dup module.next @
|
||||
swap free-memory
|
||||
repeat
|
||||
0 module_options !
|
||||
0 last_module_option !
|
||||
;
|
||||
|
||||
only forth also support-functions definitions
|
||||
|
||||
\ Variables used for processing multiple conf files
|
||||
@ -943,7 +967,6 @@ string current_file_name_ref \ used to print the file name
|
||||
\ loader_conf_files processing support functions
|
||||
|
||||
: get_conf_files ( -- addr len ) \ put addr/len on stack, reset var
|
||||
\ ." -- starting on <" conf_files strtype ." >" cr \ debugging
|
||||
conf_files strget 0 0 conf_files strset
|
||||
;
|
||||
|
||||
@ -970,7 +993,6 @@ string current_file_name_ref \ used to print the file name
|
||||
pos char+ to pos
|
||||
repeat
|
||||
addr len pos addr r@ + pos r> -
|
||||
\ 2dup ." get_file_name has " type cr \ debugging
|
||||
;
|
||||
|
||||
: get_next_file ( addr len ptr -- addr len ptr' addr' len' | 0 )
|
||||
@ -1021,25 +1043,26 @@ string current_file_name_ref \ used to print the file name
|
||||
;
|
||||
|
||||
: get_nextboot_conf_file ( -- addr len )
|
||||
nextboot_conf_file strget strdup \ XXX is the strdup a leak ?
|
||||
nextboot_conf_file strget
|
||||
;
|
||||
|
||||
: rewrite_nextboot_file ( -- )
|
||||
get_nextboot_conf_file
|
||||
O_WRONLY fopen fd !
|
||||
fd @ -1 = if EOPEN throw then
|
||||
fd @ s' nextboot_enable="NO" ' fwrite
|
||||
fd @ s' nextboot_enable="NO" ' fwrite ( fd buf len -- nwritten ) drop
|
||||
fd @ fclose
|
||||
;
|
||||
|
||||
: include_nextboot_file
|
||||
: include_nextboot_file ( -- )
|
||||
get_nextboot_conf_file
|
||||
['] peek_file catch
|
||||
['] peek_file catch if 2drop then
|
||||
nextboot? if
|
||||
get_nextboot_conf_file
|
||||
current_file_name_ref strref
|
||||
['] load_conf catch
|
||||
process_conf_errors
|
||||
['] rewrite_nextboot_file catch
|
||||
['] rewrite_nextboot_file catch if 2drop then
|
||||
then
|
||||
;
|
||||
|
||||
|
@ -69,6 +69,7 @@ static int isa_inb(int port);
|
||||
static void isa_outb(int port, int value);
|
||||
void exit(int code);
|
||||
#ifdef LOADER_ZFS_SUPPORT
|
||||
static void init_zfs_bootenv(char *currdev);
|
||||
static void i386_zfs_probe(void);
|
||||
#endif
|
||||
|
||||
@ -294,12 +295,40 @@ extract_currdev(void)
|
||||
new_currdev.d_unit = 0;
|
||||
}
|
||||
|
||||
#ifdef LOADER_ZFS_SUPPORT
|
||||
init_zfs_bootenv(zfs_fmtdev(&new_currdev));
|
||||
#endif
|
||||
|
||||
env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev),
|
||||
i386_setcurrdev, env_nounset);
|
||||
env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset,
|
||||
env_nounset);
|
||||
}
|
||||
|
||||
#ifdef LOADER_ZFS_SUPPORT
|
||||
static void
|
||||
init_zfs_bootenv(char *currdev)
|
||||
{
|
||||
char *beroot;
|
||||
|
||||
/* Remove the trailing : */
|
||||
currdev[strlen(currdev) - 1] = '\0';
|
||||
setenv("zfs_be_active", currdev, 1);
|
||||
/* Do not overwrite if already set */
|
||||
setenv("vfs.root.mountfrom", currdev, 0);
|
||||
/* Forward past zfs: */
|
||||
currdev = strchr(currdev, ':');
|
||||
currdev++;
|
||||
/* Remove the last element (current bootenv) */
|
||||
beroot = strrchr(currdev, '/');
|
||||
beroot[0] = '\0';
|
||||
|
||||
beroot = currdev;
|
||||
|
||||
setenv("zfs_be_root", beroot, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
|
||||
|
||||
static int
|
||||
@ -353,6 +382,34 @@ command_lszfs(int argc, char *argv[])
|
||||
command_errmsg = strerror(err);
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
|
||||
return (CMD_OK);
|
||||
}
|
||||
|
||||
COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments",
|
||||
command_reloadbe);
|
||||
|
||||
static int
|
||||
command_reloadbe(int argc, char *argv[])
|
||||
{
|
||||
int err;
|
||||
|
||||
if (argc > 2) {
|
||||
command_errmsg = "wrong number of arguments";
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
err = zfs_bootenv(argv[1]);
|
||||
} else {
|
||||
err = zfs_bootenv(getenv("zfs_be_root"));
|
||||
}
|
||||
|
||||
if (err != 0) {
|
||||
command_errmsg = strerror(err);
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
|
||||
return (CMD_OK);
|
||||
}
|
||||
#endif
|
||||
|
@ -585,6 +585,10 @@ handle_uboot_env_var(enum ubenv_action action, const char * var)
|
||||
*/
|
||||
if (action == UBENV_IMPORT) {
|
||||
len = strcspn(var, "=");
|
||||
if (len == 0) {
|
||||
printf("name cannot start with '=': '%s'\n", var);
|
||||
return;
|
||||
}
|
||||
if (var[len] == 0) {
|
||||
strcpy(ldvar, "uboot.");
|
||||
strncat(ldvar, var, sizeof(ldvar) - 7);
|
||||
@ -604,9 +608,11 @@ handle_uboot_env_var(enum ubenv_action action, const char * var)
|
||||
var = &var[6];
|
||||
}
|
||||
|
||||
/* If ldvar is malformed or there's no variable name left, punt. */
|
||||
if (ldvar[0] == 0 || var[0] == 0)
|
||||
/* If there is no variable name left, punt. */
|
||||
if (var[0] == 0) {
|
||||
printf("empty variable name\n");
|
||||
return;
|
||||
}
|
||||
|
||||
val = ub_env_get(var);
|
||||
if (action == UBENV_SHOW) {
|
||||
|
@ -62,6 +62,9 @@ int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec,
|
||||
char *zfs_fmtdev(void *vdev);
|
||||
int zfs_probe_dev(const char *devname, uint64_t *pool_guid);
|
||||
int zfs_list(const char *name);
|
||||
int zfs_bootenv(const char *name);
|
||||
int zfs_belist_add(const char *name);
|
||||
int zfs_set_env(void);
|
||||
|
||||
extern struct devsw zfs_dev;
|
||||
extern struct fs_ops zfs_fsops;
|
||||
|
@ -48,6 +48,10 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "zfsimpl.c"
|
||||
|
||||
/* Define the range of indexes to be populated with ZFS Boot Environments */
|
||||
#define ZFS_BE_FIRST 4
|
||||
#define ZFS_BE_LAST 8
|
||||
|
||||
static int zfs_open(const char *path, struct open_file *f);
|
||||
static int zfs_write(struct open_file *f, void *buf, size_t size, size_t *resid);
|
||||
static int zfs_close(struct open_file *f);
|
||||
@ -80,6 +84,16 @@ struct file {
|
||||
zap_leaf_phys_t *f_zap_leaf; /* zap leaf buffer */
|
||||
};
|
||||
|
||||
static int zfs_env_index;
|
||||
static int zfs_env_count;
|
||||
|
||||
SLIST_HEAD(zfs_be_list, zfs_be_entry) zfs_be_head = SLIST_HEAD_INITIALIZER(zfs_be_head);
|
||||
struct zfs_be_list *zfs_be_headp;
|
||||
struct zfs_be_entry {
|
||||
const char *name;
|
||||
SLIST_ENTRY(zfs_be_entry) entries;
|
||||
} *zfs_be, *zfs_be_tmp;
|
||||
|
||||
/*
|
||||
* Open a file.
|
||||
*/
|
||||
@ -691,6 +705,156 @@ zfs_list(const char *name)
|
||||
rv = zfs_lookup_dataset(spa, dsname, &objid);
|
||||
if (rv != 0)
|
||||
return (rv);
|
||||
rv = zfs_list_dataset(spa, objid);
|
||||
|
||||
return (zfs_list_dataset(spa, objid));
|
||||
}
|
||||
|
||||
int
|
||||
zfs_bootenv(const char *name)
|
||||
{
|
||||
static char poolname[ZFS_MAXNAMELEN], *dsname;
|
||||
char becount[4];
|
||||
uint64_t objid;
|
||||
spa_t *spa;
|
||||
int len, rv, pages, perpage, currpage;
|
||||
|
||||
if (strcmp(name, getenv("zfs_be_root")) != 0) {
|
||||
if (setenv("zfs_be_root", name, 1) != 0)
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
SLIST_INIT(&zfs_be_head);
|
||||
zfs_env_count = 0;
|
||||
len = strlen(name);
|
||||
dsname = strchr(name, '/');
|
||||
if (dsname != NULL) {
|
||||
len = dsname - name;
|
||||
dsname++;
|
||||
} else
|
||||
dsname = "";
|
||||
memcpy(poolname, name, len);
|
||||
poolname[len] = '\0';
|
||||
|
||||
spa = spa_find_by_name(poolname);
|
||||
if (!spa)
|
||||
return (ENXIO);
|
||||
rv = zfs_lookup_dataset(spa, dsname, &objid);
|
||||
if (rv != 0)
|
||||
return (rv);
|
||||
rv = zfs_callback_dataset(spa, objid, zfs_belist_add);
|
||||
|
||||
/* Calculate and store the number of pages of BEs */
|
||||
perpage = (ZFS_BE_LAST - ZFS_BE_FIRST + 1);
|
||||
pages = (zfs_env_count / perpage) + ((zfs_env_count % perpage) > 0 ? 1 : 0);
|
||||
snprintf(becount, 4, "%d", pages);
|
||||
if (setenv("zfs_be_pages", becount, 1) != 0)
|
||||
return (ENOMEM);
|
||||
|
||||
/* Roll over the page counter if it has exceeded the maximum */
|
||||
currpage = strtol(getenv("zfs_be_currpage"), NULL, 10);
|
||||
if (currpage > pages) {
|
||||
if (setenv("zfs_be_currpage", "1", 1) != 0)
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* Populate the menu environment variables */
|
||||
zfs_set_env();
|
||||
|
||||
/* Clean up the SLIST of ZFS BEs */
|
||||
while (!SLIST_EMPTY(&zfs_be_head)) {
|
||||
zfs_be = SLIST_FIRST(&zfs_be_head);
|
||||
SLIST_REMOVE_HEAD(&zfs_be_head, entries);
|
||||
free(zfs_be);
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
zfs_belist_add(const char *name)
|
||||
{
|
||||
|
||||
/* Add the boot environment to the head of the SLIST */
|
||||
zfs_be = malloc(sizeof(struct zfs_be_entry));
|
||||
zfs_be->name = name;
|
||||
SLIST_INSERT_HEAD(&zfs_be_head, zfs_be, entries);
|
||||
zfs_env_count++;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
zfs_set_env(void)
|
||||
{
|
||||
char envname[32], envval[256];
|
||||
char *beroot, *pagenum;
|
||||
int rv, page, ctr;
|
||||
|
||||
beroot = getenv("zfs_be_root");
|
||||
if (beroot == NULL) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
pagenum = getenv("zfs_be_currpage");
|
||||
if (pagenum != NULL) {
|
||||
page = strtol(pagenum, NULL, 10);
|
||||
} else {
|
||||
page = 1;
|
||||
}
|
||||
|
||||
ctr = 1;
|
||||
rv = 0;
|
||||
zfs_env_index = ZFS_BE_FIRST;
|
||||
SLIST_FOREACH_SAFE(zfs_be, &zfs_be_head, entries, zfs_be_tmp) {
|
||||
/* Skip to the requested page number */
|
||||
if (ctr <= ((ZFS_BE_LAST - ZFS_BE_FIRST + 1) * (page - 1))) {
|
||||
ctr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
|
||||
snprintf(envval, sizeof(envval), "%s", zfs_be->name);
|
||||
rv = setenv(envname, envval, 1);
|
||||
if (rv != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
|
||||
rv = setenv(envname, envval, 1);
|
||||
if (rv != 0){
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
|
||||
rv = setenv(envname, "set_bootenv", 1);
|
||||
if (rv != 0){
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
|
||||
snprintf(envval, sizeof(envval), "zfs:%s/%s", beroot, zfs_be->name);
|
||||
rv = setenv(envname, envval, 1);
|
||||
if (rv != 0){
|
||||
break;
|
||||
}
|
||||
|
||||
zfs_env_index++;
|
||||
if (zfs_env_index > ZFS_BE_LAST) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (; zfs_env_index <= ZFS_BE_LAST; zfs_env_index++) {
|
||||
snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
|
||||
(void)unsetenv(envname);
|
||||
snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
|
||||
(void)unsetenv(envname);
|
||||
snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
|
||||
(void)unsetenv(envname);
|
||||
snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
|
||||
(void)unsetenv(envname);
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
@ -1473,7 +1473,7 @@ zap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64
|
||||
* the directory contents.
|
||||
*/
|
||||
static int
|
||||
mzap_list(const dnode_phys_t *dnode)
|
||||
mzap_list(const dnode_phys_t *dnode, int (*callback)(const char *))
|
||||
{
|
||||
const mzap_phys_t *mz;
|
||||
const mzap_ent_phys_t *mze;
|
||||
@ -1492,7 +1492,7 @@ mzap_list(const dnode_phys_t *dnode)
|
||||
mze = &mz->mz_chunk[i];
|
||||
if (mze->mze_name[0])
|
||||
//printf("%-32s 0x%jx\n", mze->mze_name, (uintmax_t)mze->mze_value);
|
||||
printf("%s\n", mze->mze_name);
|
||||
callback(mze->mze_name);
|
||||
}
|
||||
|
||||
return (0);
|
||||
@ -1503,7 +1503,7 @@ mzap_list(const dnode_phys_t *dnode)
|
||||
* the directory header.
|
||||
*/
|
||||
static int
|
||||
fzap_list(const spa_t *spa, const dnode_phys_t *dnode)
|
||||
fzap_list(const spa_t *spa, const dnode_phys_t *dnode, int (*callback)(const char *))
|
||||
{
|
||||
int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
|
||||
zap_phys_t zh = *(zap_phys_t *) zap_scratch;
|
||||
@ -1566,13 +1566,21 @@ fzap_list(const spa_t *spa, const dnode_phys_t *dnode)
|
||||
value = fzap_leaf_value(&zl, zc);
|
||||
|
||||
//printf("%s 0x%jx\n", name, (uintmax_t)value);
|
||||
printf("%s\n", name);
|
||||
callback((const char *)name);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int zfs_printf(const char *name)
|
||||
{
|
||||
|
||||
printf("%s\n", name);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* List a zap directory.
|
||||
*/
|
||||
@ -1587,9 +1595,9 @@ zap_list(const spa_t *spa, const dnode_phys_t *dnode)
|
||||
|
||||
zap_type = *(uint64_t *) zap_scratch;
|
||||
if (zap_type == ZBT_MICRO)
|
||||
return mzap_list(dnode);
|
||||
return mzap_list(dnode, zfs_printf);
|
||||
else
|
||||
return fzap_list(spa, dnode);
|
||||
return fzap_list(spa, dnode, zfs_printf);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1858,6 +1866,48 @@ zfs_list_dataset(const spa_t *spa, uint64_t objnum/*, int pos, char *entry*/)
|
||||
|
||||
return (zap_list(spa, &child_dir_zap) != 0);
|
||||
}
|
||||
|
||||
int
|
||||
zfs_callback_dataset(const spa_t *spa, uint64_t objnum, int (*callback)(const char *name))
|
||||
{
|
||||
uint64_t dir_obj, child_dir_zapobj, zap_type;
|
||||
dnode_phys_t child_dir_zap, dir, dataset;
|
||||
dsl_dataset_phys_t *ds;
|
||||
dsl_dir_phys_t *dd;
|
||||
int err;
|
||||
|
||||
err = objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset);
|
||||
if (err != 0) {
|
||||
printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum);
|
||||
return (err);
|
||||
}
|
||||
ds = (dsl_dataset_phys_t *) &dataset.dn_bonus;
|
||||
dir_obj = ds->ds_dir_obj;
|
||||
|
||||
err = objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir);
|
||||
if (err != 0) {
|
||||
printf("ZFS: can't find dirobj %ju\n", (uintmax_t)dir_obj);
|
||||
return (err);
|
||||
}
|
||||
dd = (dsl_dir_phys_t *)&dir.dn_bonus;
|
||||
|
||||
child_dir_zapobj = dd->dd_child_dir_zapobj;
|
||||
err = objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap);
|
||||
if (err != 0) {
|
||||
printf("ZFS: can't find child zap %ju\n", (uintmax_t)dir_obj);
|
||||
return (err);
|
||||
}
|
||||
|
||||
err = dnode_read(spa, &child_dir_zap, 0, zap_scratch, child_dir_zap.dn_datablkszsec * 512);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
|
||||
zap_type = *(uint64_t *) zap_scratch;
|
||||
if (zap_type == ZBT_MICRO)
|
||||
return mzap_list(&child_dir_zap, callback);
|
||||
else
|
||||
return fzap_list(spa, &child_dir_zap, callback);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -41,6 +41,8 @@ struct inode;
|
||||
struct module;
|
||||
|
||||
extern struct cdevsw linuxcdevsw;
|
||||
extern const struct kobj_type linux_cdev_ktype;
|
||||
extern const struct kobj_type linux_cdev_static_ktype;
|
||||
|
||||
struct linux_cdev {
|
||||
struct kobject kobj;
|
||||
@ -50,40 +52,11 @@ struct linux_cdev {
|
||||
const struct file_operations *ops;
|
||||
};
|
||||
|
||||
static inline void
|
||||
cdev_release(struct kobject *kobj)
|
||||
{
|
||||
struct linux_cdev *cdev;
|
||||
|
||||
cdev = container_of(kobj, struct linux_cdev, kobj);
|
||||
if (cdev->cdev)
|
||||
destroy_dev(cdev->cdev);
|
||||
kfree(cdev);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cdev_static_release(struct kobject *kobj)
|
||||
{
|
||||
struct linux_cdev *cdev;
|
||||
|
||||
cdev = container_of(kobj, struct linux_cdev, kobj);
|
||||
if (cdev->cdev)
|
||||
destroy_dev(cdev->cdev);
|
||||
}
|
||||
|
||||
static struct kobj_type cdev_ktype = {
|
||||
.release = cdev_release,
|
||||
};
|
||||
|
||||
static struct kobj_type cdev_static_ktype = {
|
||||
.release = cdev_static_release,
|
||||
};
|
||||
|
||||
static inline void
|
||||
cdev_init(struct linux_cdev *cdev, const struct file_operations *ops)
|
||||
{
|
||||
|
||||
kobject_init(&cdev->kobj, &cdev_static_ktype);
|
||||
kobject_init(&cdev->kobj, &linux_cdev_static_ktype);
|
||||
cdev->ops = ops;
|
||||
}
|
||||
|
||||
@ -94,7 +67,7 @@ cdev_alloc(void)
|
||||
|
||||
cdev = kzalloc(sizeof(struct linux_cdev), M_WAITOK);
|
||||
if (cdev)
|
||||
kobject_init(&cdev->kobj, &cdev_ktype);
|
||||
kobject_init(&cdev->kobj, &linux_cdev_ktype);
|
||||
return (cdev);
|
||||
}
|
||||
|
||||
@ -114,6 +87,7 @@ cdev_add(struct linux_cdev *cdev, dev_t dev, unsigned count)
|
||||
cdev->dev = dev;
|
||||
cdev->cdev->si_drv1 = cdev;
|
||||
|
||||
kobject_get(cdev->kobj.parent);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -73,8 +73,10 @@ struct device {
|
||||
unsigned int msix_max;
|
||||
};
|
||||
|
||||
extern struct device linux_rootdev;
|
||||
extern struct kobject class_root;
|
||||
extern struct device linux_root_device;
|
||||
extern struct kobject linux_class_root;
|
||||
extern const struct kobj_type linux_dev_ktype;
|
||||
extern const struct kobj_type linux_class_ktype;
|
||||
|
||||
struct class_attribute {
|
||||
struct attribute attr;
|
||||
@ -170,62 +172,14 @@ put_device(struct device *dev)
|
||||
kobject_put(&dev->kobj);
|
||||
}
|
||||
|
||||
static inline ssize_t
|
||||
class_show(struct kobject *kobj, struct attribute *attr, char *buf)
|
||||
{
|
||||
struct class_attribute *dattr;
|
||||
ssize_t error;
|
||||
|
||||
dattr = container_of(attr, struct class_attribute, attr);
|
||||
error = -EIO;
|
||||
if (dattr->show)
|
||||
error = dattr->show(container_of(kobj, struct class, kobj),
|
||||
dattr, buf);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static inline ssize_t
|
||||
class_store(struct kobject *kobj, struct attribute *attr, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct class_attribute *dattr;
|
||||
ssize_t error;
|
||||
|
||||
dattr = container_of(attr, struct class_attribute, attr);
|
||||
error = -EIO;
|
||||
if (dattr->store)
|
||||
error = dattr->store(container_of(kobj, struct class, kobj),
|
||||
dattr, buf, count);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static inline void
|
||||
class_release(struct kobject *kobj)
|
||||
{
|
||||
struct class *class;
|
||||
|
||||
class = container_of(kobj, struct class, kobj);
|
||||
if (class->class_release)
|
||||
class->class_release(class);
|
||||
}
|
||||
|
||||
static struct sysfs_ops class_sysfs = {
|
||||
.show = class_show,
|
||||
.store = class_store,
|
||||
};
|
||||
static struct kobj_type class_ktype = {
|
||||
.release = class_release,
|
||||
.sysfs_ops = &class_sysfs
|
||||
};
|
||||
|
||||
static inline int
|
||||
class_register(struct class *class)
|
||||
{
|
||||
|
||||
class->bsdclass = devclass_create(class->name);
|
||||
kobject_init(&class->kobj, &class_ktype);
|
||||
kobject_init(&class->kobj, &linux_class_ktype);
|
||||
kobject_set_name(&class->kobj, class->name);
|
||||
kobject_add(&class->kobj, &class_root, class->name);
|
||||
kobject_add(&class->kobj, &linux_class_root, class->name);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -237,54 +191,6 @@ class_unregister(struct class *class)
|
||||
kobject_put(&class->kobj);
|
||||
}
|
||||
|
||||
static inline void
|
||||
device_release(struct kobject *kobj)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = container_of(kobj, struct device, kobj);
|
||||
/* This is the precedence defined by linux. */
|
||||
if (dev->release)
|
||||
dev->release(dev);
|
||||
else if (dev->class && dev->class->dev_release)
|
||||
dev->class->dev_release(dev);
|
||||
}
|
||||
|
||||
static inline ssize_t
|
||||
dev_show(struct kobject *kobj, struct attribute *attr, char *buf)
|
||||
{
|
||||
struct device_attribute *dattr;
|
||||
ssize_t error;
|
||||
|
||||
dattr = container_of(attr, struct device_attribute, attr);
|
||||
error = -EIO;
|
||||
if (dattr->show)
|
||||
error = dattr->show(container_of(kobj, struct device, kobj),
|
||||
dattr, buf);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static inline ssize_t
|
||||
dev_store(struct kobject *kobj, struct attribute *attr, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct device_attribute *dattr;
|
||||
ssize_t error;
|
||||
|
||||
dattr = container_of(attr, struct device_attribute, attr);
|
||||
error = -EIO;
|
||||
if (dattr->store)
|
||||
error = dattr->store(container_of(kobj, struct device, kobj),
|
||||
dattr, buf, count);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static struct sysfs_ops dev_sysfs = { .show = dev_show, .store = dev_store, };
|
||||
static struct kobj_type dev_ktype = {
|
||||
.release = device_release,
|
||||
.sysfs_ops = &dev_sysfs
|
||||
};
|
||||
|
||||
/*
|
||||
* Devices are registered and created for exporting to sysfs. create
|
||||
* implies register and register assumes the device fields have been
|
||||
@ -311,7 +217,7 @@ device_register(struct device *dev)
|
||||
device_set_softc(bsddev, dev);
|
||||
}
|
||||
dev->bsddev = bsddev;
|
||||
kobject_init(&dev->kobj, &dev_ktype);
|
||||
kobject_init(&dev->kobj, &linux_dev_ktype);
|
||||
kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev));
|
||||
|
||||
return (0);
|
||||
@ -346,7 +252,7 @@ device_destroy(struct class *class, dev_t devt)
|
||||
}
|
||||
|
||||
static inline void
|
||||
class_kfree(struct class *class)
|
||||
linux_class_kfree(struct class *class)
|
||||
{
|
||||
|
||||
kfree(class);
|
||||
@ -361,7 +267,7 @@ class_create(struct module *owner, const char *name)
|
||||
class = kzalloc(sizeof(*class), M_WAITOK);
|
||||
class->owner = owner;
|
||||
class->name= name;
|
||||
class->class_release = class_kfree;
|
||||
class->class_release = linux_class_kfree;
|
||||
error = class_register(class);
|
||||
if (error) {
|
||||
kfree(class);
|
||||
@ -414,7 +320,8 @@ class_remove_file(struct class *class, const struct class_attribute *attr)
|
||||
sysfs_remove_file(&class->kobj, &attr->attr);
|
||||
}
|
||||
|
||||
static inline int dev_to_node(struct device *dev)
|
||||
static inline int
|
||||
dev_to_node(struct device *dev)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -101,10 +101,11 @@ fd_install(unsigned int fd, struct linux_file *filp)
|
||||
|
||||
if (fget_unlocked(curthread->td_proc->p_fd, fd,
|
||||
cap_rights_init(&rights), &file, NULL) != 0) {
|
||||
file = NULL;
|
||||
filp->_file = NULL;
|
||||
} else {
|
||||
filp->_file = file;
|
||||
finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
|
||||
}
|
||||
filp->_file = file;
|
||||
finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
|
||||
|
||||
/* drop the extra reference */
|
||||
fput(filp);
|
||||
|
@ -46,13 +46,13 @@ struct kobj_type {
|
||||
struct attribute **default_attrs;
|
||||
};
|
||||
|
||||
extern struct kobj_type kfree_type;
|
||||
extern const struct kobj_type linux_kfree_type;
|
||||
|
||||
struct kobject {
|
||||
struct kobject *parent;
|
||||
char *name;
|
||||
struct kref kref;
|
||||
struct kobj_type *ktype;
|
||||
const struct kobj_type *ktype;
|
||||
struct list_head entry;
|
||||
struct sysctl_oid *oidp;
|
||||
};
|
||||
@ -74,7 +74,7 @@ struct kobj_attribute {
|
||||
};
|
||||
|
||||
static inline void
|
||||
kobject_init(struct kobject *kobj, struct kobj_type *ktype)
|
||||
kobject_init(struct kobject *kobj, const struct kobj_type *ktype)
|
||||
{
|
||||
|
||||
kref_init(&kobj->kref);
|
||||
@ -83,15 +83,14 @@ kobject_init(struct kobject *kobj, struct kobj_type *ktype)
|
||||
kobj->oidp = NULL;
|
||||
}
|
||||
|
||||
static inline void kobject_put(struct kobject *kobj);
|
||||
void kobject_release(struct kref *kref);
|
||||
void linux_kobject_release(struct kref *kref);
|
||||
|
||||
static inline void
|
||||
kobject_put(struct kobject *kobj)
|
||||
{
|
||||
|
||||
if (kobj)
|
||||
kref_put(&kobj->kref, kobject_release);
|
||||
kref_put(&kobj->kref, linux_kobject_release);
|
||||
}
|
||||
|
||||
static inline struct kobject *
|
||||
@ -115,7 +114,7 @@ kobject_create(void)
|
||||
kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
|
||||
if (kobj == NULL)
|
||||
return (NULL);
|
||||
kobject_init(kobj, &kfree_type);
|
||||
kobject_init(kobj, &linux_kfree_type);
|
||||
|
||||
return (kobj);
|
||||
}
|
||||
@ -135,7 +134,6 @@ kobject_create_and_add(const char *name, struct kobject *parent)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
static inline char *
|
||||
kobject_name(const struct kobject *kobj)
|
||||
{
|
||||
@ -144,7 +142,7 @@ kobject_name(const struct kobject *kobj)
|
||||
}
|
||||
|
||||
int kobject_set_name(struct kobject *kobj, const char *fmt, ...);
|
||||
int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
|
||||
int kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype,
|
||||
struct kobject *parent, const char *fmt, ...);
|
||||
|
||||
#endif /* _LINUX_KOBJECT_H_ */
|
||||
|
@ -46,13 +46,13 @@ struct miscdevice {
|
||||
umode_t mode;
|
||||
};
|
||||
|
||||
extern struct class miscclass;
|
||||
extern struct class linux_class_misc;
|
||||
|
||||
static inline int
|
||||
misc_register(struct miscdevice *misc)
|
||||
{
|
||||
misc->this_device = device_create(&miscclass, &linux_rootdev, 0, misc,
|
||||
misc->name);
|
||||
misc->this_device = device_create(&linux_class_misc,
|
||||
&linux_root_device, 0, misc, misc->name);
|
||||
misc->cdev = cdev_alloc();
|
||||
if (misc->cdev == NULL)
|
||||
return -ENOMEM;
|
||||
@ -67,7 +67,7 @@ misc_register(struct miscdevice *misc)
|
||||
static inline int
|
||||
misc_deregister(struct miscdevice *misc)
|
||||
{
|
||||
device_destroy(&miscclass, misc->this_device->devt);
|
||||
device_destroy(&linux_class_misc, misc->this_device->devt);
|
||||
cdev_del(misc->cdev);
|
||||
|
||||
return (0);
|
||||
|
@ -77,9 +77,9 @@ MALLOC_DEFINE(M_KMALLOC, "linux", "Linux kmalloc compat");
|
||||
#undef cdev
|
||||
#define RB_ROOT(head) (head)->rbh_root
|
||||
|
||||
struct kobject class_root;
|
||||
struct device linux_rootdev;
|
||||
struct class miscclass;
|
||||
struct kobject linux_class_root;
|
||||
struct device linux_root_device;
|
||||
struct class linux_class_misc;
|
||||
struct list_head pci_drivers;
|
||||
struct list_head pci_devices;
|
||||
struct net init_net;
|
||||
@ -151,13 +151,13 @@ kobject_set_name(struct kobject *kobj, const char *fmt, ...)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static inline int
|
||||
static int
|
||||
kobject_add_complete(struct kobject *kobj, struct kobject *parent)
|
||||
{
|
||||
struct kobj_type *t;
|
||||
const struct kobj_type *t;
|
||||
int error;
|
||||
|
||||
kobj->parent = kobject_get(parent);
|
||||
kobj->parent = parent;
|
||||
error = sysfs_create_dir(kobj);
|
||||
if (error == 0 && kobj->ktype && kobj->ktype->default_attrs) {
|
||||
struct attribute **attr;
|
||||
@ -191,16 +191,13 @@ kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...)
|
||||
}
|
||||
|
||||
void
|
||||
kobject_release(struct kref *kref)
|
||||
linux_kobject_release(struct kref *kref)
|
||||
{
|
||||
struct kobject *kobj;
|
||||
char *name;
|
||||
|
||||
kobj = container_of(kref, struct kobject, kref);
|
||||
sysfs_remove_dir(kobj);
|
||||
if (kobj->parent)
|
||||
kobject_put(kobj->parent);
|
||||
kobj->parent = NULL;
|
||||
name = kobj->name;
|
||||
if (kobj->ktype && kobj->ktype->release)
|
||||
kobj->ktype->release(kobj);
|
||||
@ -208,28 +205,131 @@ kobject_release(struct kref *kref)
|
||||
}
|
||||
|
||||
static void
|
||||
kobject_kfree(struct kobject *kobj)
|
||||
linux_kobject_kfree(struct kobject *kobj)
|
||||
{
|
||||
kfree(kobj);
|
||||
}
|
||||
|
||||
static void
|
||||
kobject_kfree_name(struct kobject *kobj)
|
||||
linux_kobject_kfree_name(struct kobject *kobj)
|
||||
{
|
||||
if (kobj) {
|
||||
kfree(kobj->name);
|
||||
}
|
||||
}
|
||||
|
||||
struct kobj_type kfree_type = { .release = kobject_kfree };
|
||||
const struct kobj_type linux_kfree_type = {
|
||||
.release = linux_kobject_kfree
|
||||
};
|
||||
|
||||
static void
|
||||
dev_release(struct device *dev)
|
||||
linux_device_release(struct device *dev)
|
||||
{
|
||||
pr_debug("dev_release: %s\n", dev_name(dev));
|
||||
pr_debug("linux_device_release: %s\n", dev_name(dev));
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
linux_class_show(struct kobject *kobj, struct attribute *attr, char *buf)
|
||||
{
|
||||
struct class_attribute *dattr;
|
||||
ssize_t error;
|
||||
|
||||
dattr = container_of(attr, struct class_attribute, attr);
|
||||
error = -EIO;
|
||||
if (dattr->show)
|
||||
error = dattr->show(container_of(kobj, struct class, kobj),
|
||||
dattr, buf);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
linux_class_store(struct kobject *kobj, struct attribute *attr, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct class_attribute *dattr;
|
||||
ssize_t error;
|
||||
|
||||
dattr = container_of(attr, struct class_attribute, attr);
|
||||
error = -EIO;
|
||||
if (dattr->store)
|
||||
error = dattr->store(container_of(kobj, struct class, kobj),
|
||||
dattr, buf, count);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
linux_class_release(struct kobject *kobj)
|
||||
{
|
||||
struct class *class;
|
||||
|
||||
class = container_of(kobj, struct class, kobj);
|
||||
if (class->class_release)
|
||||
class->class_release(class);
|
||||
}
|
||||
|
||||
static const struct sysfs_ops linux_class_sysfs = {
|
||||
.show = linux_class_show,
|
||||
.store = linux_class_store,
|
||||
};
|
||||
|
||||
const struct kobj_type linux_class_ktype = {
|
||||
.release = linux_class_release,
|
||||
.sysfs_ops = &linux_class_sysfs
|
||||
};
|
||||
|
||||
static void
|
||||
linux_dev_release(struct kobject *kobj)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = container_of(kobj, struct device, kobj);
|
||||
/* This is the precedence defined by linux. */
|
||||
if (dev->release)
|
||||
dev->release(dev);
|
||||
else if (dev->class && dev->class->dev_release)
|
||||
dev->class->dev_release(dev);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
linux_dev_show(struct kobject *kobj, struct attribute *attr, char *buf)
|
||||
{
|
||||
struct device_attribute *dattr;
|
||||
ssize_t error;
|
||||
|
||||
dattr = container_of(attr, struct device_attribute, attr);
|
||||
error = -EIO;
|
||||
if (dattr->show)
|
||||
error = dattr->show(container_of(kobj, struct device, kobj),
|
||||
dattr, buf);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
linux_dev_store(struct kobject *kobj, struct attribute *attr, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct device_attribute *dattr;
|
||||
ssize_t error;
|
||||
|
||||
dattr = container_of(attr, struct device_attribute, attr);
|
||||
error = -EIO;
|
||||
if (dattr->store)
|
||||
error = dattr->store(container_of(kobj, struct device, kobj),
|
||||
dattr, buf, count);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static const struct sysfs_ops linux_dev_sysfs = {
|
||||
.show = linux_dev_show,
|
||||
.store = linux_dev_store,
|
||||
};
|
||||
|
||||
const struct kobj_type linux_dev_ktype = {
|
||||
.release = linux_dev_release,
|
||||
.sysfs_ops = &linux_dev_sysfs
|
||||
};
|
||||
|
||||
struct device *
|
||||
device_create(struct class *class, struct device *parent, dev_t devt,
|
||||
void *drvdata, const char *fmt, ...)
|
||||
@ -242,7 +342,7 @@ device_create(struct class *class, struct device *parent, dev_t devt,
|
||||
dev->class = class;
|
||||
dev->devt = devt;
|
||||
dev->driver_data = drvdata;
|
||||
dev->release = dev_release;
|
||||
dev->release = linux_device_release;
|
||||
va_start(args, fmt);
|
||||
kobject_set_name_vargs(&dev->kobj, fmt, args);
|
||||
va_end(args);
|
||||
@ -252,7 +352,7 @@ device_create(struct class *class, struct device *parent, dev_t devt,
|
||||
}
|
||||
|
||||
int
|
||||
kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
|
||||
kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype,
|
||||
struct kobject *parent, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
@ -1001,6 +1101,41 @@ destroy_workqueue(struct workqueue_struct *wq)
|
||||
kfree(wq);
|
||||
}
|
||||
|
||||
static void
|
||||
linux_cdev_release(struct kobject *kobj)
|
||||
{
|
||||
struct linux_cdev *cdev;
|
||||
struct kobject *parent;
|
||||
|
||||
cdev = container_of(kobj, struct linux_cdev, kobj);
|
||||
parent = kobj->parent;
|
||||
if (cdev->cdev)
|
||||
destroy_dev(cdev->cdev);
|
||||
kfree(cdev);
|
||||
kobject_put(parent);
|
||||
}
|
||||
|
||||
static void
|
||||
linux_cdev_static_release(struct kobject *kobj)
|
||||
{
|
||||
struct linux_cdev *cdev;
|
||||
struct kobject *parent;
|
||||
|
||||
cdev = container_of(kobj, struct linux_cdev, kobj);
|
||||
parent = kobj->parent;
|
||||
if (cdev->cdev)
|
||||
destroy_dev(cdev->cdev);
|
||||
kobject_put(parent);
|
||||
}
|
||||
|
||||
const struct kobj_type linux_cdev_ktype = {
|
||||
.release = linux_cdev_release,
|
||||
};
|
||||
|
||||
const struct kobj_type linux_cdev_static_ktype = {
|
||||
.release = linux_cdev_static_release,
|
||||
};
|
||||
|
||||
static void
|
||||
linux_compat_init(void *arg)
|
||||
{
|
||||
@ -1009,18 +1144,18 @@ linux_compat_init(void *arg)
|
||||
|
||||
rootoid = SYSCTL_ADD_ROOT_NODE(NULL,
|
||||
OID_AUTO, "sys", CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, "sys");
|
||||
kobject_init(&class_root, &class_ktype);
|
||||
kobject_set_name(&class_root, "class");
|
||||
class_root.oidp = SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(rootoid),
|
||||
kobject_init(&linux_class_root, &linux_class_ktype);
|
||||
kobject_set_name(&linux_class_root, "class");
|
||||
linux_class_root.oidp = SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(rootoid),
|
||||
OID_AUTO, "class", CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, "class");
|
||||
kobject_init(&linux_rootdev.kobj, &dev_ktype);
|
||||
kobject_set_name(&linux_rootdev.kobj, "device");
|
||||
linux_rootdev.kobj.oidp = SYSCTL_ADD_NODE(NULL,
|
||||
kobject_init(&linux_root_device.kobj, &linux_dev_ktype);
|
||||
kobject_set_name(&linux_root_device.kobj, "device");
|
||||
linux_root_device.kobj.oidp = SYSCTL_ADD_NODE(NULL,
|
||||
SYSCTL_CHILDREN(rootoid), OID_AUTO, "device", CTLFLAG_RD, NULL,
|
||||
"device");
|
||||
linux_rootdev.bsddev = root_bus;
|
||||
miscclass.name = "misc";
|
||||
class_register(&miscclass);
|
||||
linux_root_device.bsddev = root_bus;
|
||||
linux_class_misc.name = "misc";
|
||||
class_register(&linux_class_misc);
|
||||
INIT_LIST_HEAD(&pci_drivers);
|
||||
INIT_LIST_HEAD(&pci_devices);
|
||||
spin_lock_init(&pci_lock);
|
||||
@ -1033,9 +1168,9 @@ SYSINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_init, NULL);
|
||||
static void
|
||||
linux_compat_uninit(void *arg)
|
||||
{
|
||||
kobject_kfree_name(&class_root);
|
||||
kobject_kfree_name(&linux_rootdev.kobj);
|
||||
kobject_kfree_name(&miscclass.kobj);
|
||||
linux_kobject_kfree_name(&linux_class_root);
|
||||
linux_kobject_kfree_name(&linux_root_device.kobj);
|
||||
linux_kobject_kfree_name(&linux_class_misc.kobj);
|
||||
}
|
||||
SYSUNINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_uninit, NULL);
|
||||
|
||||
|
@ -119,16 +119,16 @@ linux_pci_attach(device_t dev)
|
||||
|
||||
pdrv = linux_pci_find(dev, &id);
|
||||
pdev = device_get_softc(dev);
|
||||
pdev->dev.parent = &linux_rootdev;
|
||||
pdev->dev.parent = &linux_root_device;
|
||||
pdev->dev.bsddev = dev;
|
||||
INIT_LIST_HEAD(&pdev->dev.irqents);
|
||||
pdev->device = id->device;
|
||||
pdev->vendor = id->vendor;
|
||||
pdev->dev.dma_mask = &pdev->dma_mask;
|
||||
pdev->pdrv = pdrv;
|
||||
kobject_init(&pdev->dev.kobj, &dev_ktype);
|
||||
kobject_init(&pdev->dev.kobj, &linux_dev_ktype);
|
||||
kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev));
|
||||
kobject_add(&pdev->dev.kobj, &linux_rootdev.kobj,
|
||||
kobject_add(&pdev->dev.kobj, &linux_root_device.kobj,
|
||||
kobject_name(&pdev->dev.kobj));
|
||||
rle = _pci_get_rle(pdev, SYS_RES_IRQ, 0);
|
||||
if (rle)
|
||||
|
@ -97,7 +97,10 @@ then
|
||||
fi
|
||||
|
||||
touch version
|
||||
v=`cat version` u=${USER:-root} d=`pwd` h=${HOSTNAME:-`hostname`}
|
||||
v=`cat version`
|
||||
u=${USER:-root}
|
||||
d=`pwd`
|
||||
h=${HOSTNAME:-`hostname`}
|
||||
if [ -n "$SOURCE_DATE_EPOCH" ]; then
|
||||
if ! t=`date -r $SOURCE_DATE_EPOCH 2>/dev/null`; then
|
||||
echo "Invalid SOURCE_DATE_EPOCH" >&2
|
||||
|
@ -53,6 +53,7 @@ struct sha1_ctxt {
|
||||
} m;
|
||||
u_int8_t count;
|
||||
};
|
||||
typedef struct sha1_ctxt SHA1_CTX;
|
||||
|
||||
#ifdef _KERNEL
|
||||
extern void sha1_init(struct sha1_ctxt *);
|
||||
@ -61,7 +62,6 @@ extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
|
||||
extern void sha1_result(struct sha1_ctxt *, caddr_t);
|
||||
|
||||
/* compatibilty with other SHA1 source codes */
|
||||
typedef struct sha1_ctxt SHA1_CTX;
|
||||
#define SHA1Init(x) sha1_init((x))
|
||||
#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
|
||||
#define SHA1Final(x, y) sha1_result((y), (x))
|
||||
|
@ -215,7 +215,7 @@ resolve_entry(struct adapter *sc, struct l2t_entry *e)
|
||||
struct tom_data *td = sc->tom_softc;
|
||||
struct toedev *tod = &td->tod;
|
||||
struct sockaddr_in sin = {0};
|
||||
uint8_t dmac[ETHER_ADDR_LEN];
|
||||
uint8_t dmac[ETHER_HDR_LEN];
|
||||
uint16_t vtag = EVL_VLID_MASK;
|
||||
int rc;
|
||||
|
||||
|
@ -233,7 +233,7 @@ resolve_entry(struct adapter *sc, struct l2t_entry *e)
|
||||
struct sockaddr_in sin = {0};
|
||||
struct sockaddr_in6 sin6 = {0};
|
||||
struct sockaddr *sa;
|
||||
uint8_t dmac[ETHER_ADDR_LEN];
|
||||
uint8_t dmac[ETHER_HDR_LEN];
|
||||
uint16_t vtag = VLAN_NONE;
|
||||
int rc;
|
||||
|
||||
|
@ -698,7 +698,7 @@ enum mlx5e_link_mode {
|
||||
MLX5E_56GBASE_R4 = 8,
|
||||
MLX5E_10GBASE_CR = 12,
|
||||
MLX5E_10GBASE_SR = 13,
|
||||
MLX5E_10GBASE_ER = 14,
|
||||
MLX5E_10GBASE_LR = 14,
|
||||
MLX5E_40GBASE_SR4 = 15,
|
||||
MLX5E_40GBASE_LR4 = 16,
|
||||
MLX5E_100GBASE_CR4 = 20,
|
||||
@ -787,5 +787,6 @@ void mlx5e_create_stats(struct sysctl_ctx_list *,
|
||||
struct sysctl_oid_list *, const char *,
|
||||
const char **, unsigned, u64 *);
|
||||
void mlx5e_send_nop(struct mlx5e_sq *, u32, bool);
|
||||
int mlx5e_refresh_channel_params(struct mlx5e_priv *);
|
||||
|
||||
#endif /* _MLX5_EN_H_ */
|
||||
|
@ -69,12 +69,49 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
|
||||
} else {
|
||||
error = 0;
|
||||
}
|
||||
|
||||
/* check if device is gone */
|
||||
if (priv->gone) {
|
||||
error = ENXIO;
|
||||
goto done;
|
||||
}
|
||||
/* import RX coal time */
|
||||
if (priv->params_ethtool.rx_coalesce_usecs < 1)
|
||||
priv->params_ethtool.rx_coalesce_usecs = 0;
|
||||
else if (priv->params_ethtool.rx_coalesce_usecs >
|
||||
MLX5E_FLD_MAX(cqc, cq_period)) {
|
||||
priv->params_ethtool.rx_coalesce_usecs =
|
||||
MLX5E_FLD_MAX(cqc, cq_period);
|
||||
}
|
||||
priv->params.rx_cq_moderation_usec = priv->params_ethtool.rx_coalesce_usecs;
|
||||
|
||||
/* import RX coal pkts */
|
||||
if (priv->params_ethtool.rx_coalesce_pkts < 1)
|
||||
priv->params_ethtool.rx_coalesce_pkts = 0;
|
||||
else if (priv->params_ethtool.rx_coalesce_pkts >
|
||||
MLX5E_FLD_MAX(cqc, cq_max_count)) {
|
||||
priv->params_ethtool.rx_coalesce_pkts =
|
||||
MLX5E_FLD_MAX(cqc, cq_max_count);
|
||||
}
|
||||
priv->params.rx_cq_moderation_pkts = priv->params_ethtool.rx_coalesce_pkts;
|
||||
|
||||
/* import TX coal time */
|
||||
if (priv->params_ethtool.tx_coalesce_usecs < 1)
|
||||
priv->params_ethtool.tx_coalesce_usecs = 0;
|
||||
else if (priv->params_ethtool.tx_coalesce_usecs >
|
||||
MLX5E_FLD_MAX(cqc, cq_period)) {
|
||||
priv->params_ethtool.tx_coalesce_usecs =
|
||||
MLX5E_FLD_MAX(cqc, cq_period);
|
||||
}
|
||||
priv->params.tx_cq_moderation_usec = priv->params_ethtool.tx_coalesce_usecs;
|
||||
|
||||
/* import TX coal pkts */
|
||||
if (priv->params_ethtool.tx_coalesce_pkts < 1)
|
||||
priv->params_ethtool.tx_coalesce_pkts = 0;
|
||||
else if (priv->params_ethtool.tx_coalesce_pkts >
|
||||
MLX5E_FLD_MAX(cqc, cq_max_count)) {
|
||||
priv->params_ethtool.tx_coalesce_pkts = MLX5E_FLD_MAX(cqc, cq_max_count);
|
||||
}
|
||||
priv->params.tx_cq_moderation_pkts = priv->params_ethtool.tx_coalesce_pkts;
|
||||
|
||||
if (&priv->params_ethtool.arg[arg2] == &priv->params_ethtool.rx_pauseframe_control ||
|
||||
&priv->params_ethtool.arg[arg2] == &priv->params_ethtool.tx_pauseframe_control) {
|
||||
@ -92,9 +129,19 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
|
||||
}
|
||||
|
||||
was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
|
||||
if (was_opened)
|
||||
mlx5e_close_locked(priv->ifp);
|
||||
if (was_opened) {
|
||||
u64 *xarg = priv->params_ethtool.arg + arg2;
|
||||
|
||||
if (xarg == &priv->params_ethtool.tx_coalesce_pkts ||
|
||||
xarg == &priv->params_ethtool.rx_coalesce_pkts ||
|
||||
xarg == &priv->params_ethtool.tx_coalesce_usecs ||
|
||||
xarg == &priv->params_ethtool.rx_coalesce_usecs) {
|
||||
/* avoid downing and upping the network interface */
|
||||
error = mlx5e_refresh_channel_params(priv);
|
||||
goto done;
|
||||
}
|
||||
mlx5e_close_locked(priv->ifp);
|
||||
}
|
||||
/* import TX queue size */
|
||||
if (priv->params_ethtool.tx_queue_size <
|
||||
(1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
|
||||
@ -145,45 +192,6 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
|
||||
priv->params_ethtool.tx_coalesce_mode = 1;
|
||||
priv->params.tx_cq_moderation_mode = priv->params_ethtool.tx_coalesce_mode;
|
||||
|
||||
/* import RX coal time */
|
||||
if (priv->params_ethtool.rx_coalesce_usecs < 1)
|
||||
priv->params_ethtool.rx_coalesce_usecs = 0;
|
||||
else if (priv->params_ethtool.rx_coalesce_usecs >
|
||||
MLX5E_FLD_MAX(cqc, cq_period)) {
|
||||
priv->params_ethtool.rx_coalesce_usecs =
|
||||
MLX5E_FLD_MAX(cqc, cq_period);
|
||||
}
|
||||
priv->params.rx_cq_moderation_usec = priv->params_ethtool.rx_coalesce_usecs;
|
||||
|
||||
/* import RX coal pkts */
|
||||
if (priv->params_ethtool.rx_coalesce_pkts < 1)
|
||||
priv->params_ethtool.rx_coalesce_pkts = 0;
|
||||
else if (priv->params_ethtool.rx_coalesce_pkts >
|
||||
MLX5E_FLD_MAX(cqc, cq_max_count)) {
|
||||
priv->params_ethtool.rx_coalesce_pkts =
|
||||
MLX5E_FLD_MAX(cqc, cq_max_count);
|
||||
}
|
||||
priv->params.rx_cq_moderation_pkts = priv->params_ethtool.rx_coalesce_pkts;
|
||||
|
||||
/* import TX coal time */
|
||||
if (priv->params_ethtool.tx_coalesce_usecs < 1)
|
||||
priv->params_ethtool.tx_coalesce_usecs = 0;
|
||||
else if (priv->params_ethtool.tx_coalesce_usecs >
|
||||
MLX5E_FLD_MAX(cqc, cq_period)) {
|
||||
priv->params_ethtool.tx_coalesce_usecs =
|
||||
MLX5E_FLD_MAX(cqc, cq_period);
|
||||
}
|
||||
priv->params.tx_cq_moderation_usec = priv->params_ethtool.tx_coalesce_usecs;
|
||||
|
||||
/* import TX coal pkts */
|
||||
if (priv->params_ethtool.tx_coalesce_pkts < 1)
|
||||
priv->params_ethtool.tx_coalesce_pkts = 0;
|
||||
else if (priv->params_ethtool.tx_coalesce_pkts >
|
||||
MLX5E_FLD_MAX(cqc, cq_max_count)) {
|
||||
priv->params_ethtool.tx_coalesce_pkts = MLX5E_FLD_MAX(cqc, cq_max_count);
|
||||
}
|
||||
priv->params.tx_cq_moderation_pkts = priv->params_ethtool.tx_coalesce_pkts;
|
||||
|
||||
/* we always agree to turn off HW LRO - but not always to turn on */
|
||||
if (priv->params_ethtool.hw_lro) {
|
||||
if (priv->params_ethtool.hw_lro != 1) {
|
||||
|
@ -106,8 +106,8 @@ static const struct {
|
||||
.subtype = IFM_10G_SR,
|
||||
.baudrate = IF_Gbps(10ULL),
|
||||
},
|
||||
[MLX5E_10GBASE_ER] = {
|
||||
.subtype = IFM_10G_ER,
|
||||
[MLX5E_10GBASE_LR] = {
|
||||
.subtype = IFM_10G_LR,
|
||||
.baudrate = IF_Gbps(10ULL),
|
||||
},
|
||||
[MLX5E_40GBASE_SR4] = {
|
||||
@ -1711,6 +1711,62 @@ mlx5e_close_channels(struct mlx5e_priv *priv)
|
||||
free(ptr, M_MLX5EN);
|
||||
}
|
||||
|
||||
static int
|
||||
mlx5e_refresh_sq_params(struct mlx5e_priv *priv, struct mlx5e_sq *sq)
|
||||
{
|
||||
return (mlx5_core_modify_cq_moderation(priv->mdev, &sq->cq.mcq,
|
||||
priv->params.tx_cq_moderation_usec,
|
||||
priv->params.tx_cq_moderation_pkts));
|
||||
}
|
||||
|
||||
static int
|
||||
mlx5e_refresh_rq_params(struct mlx5e_priv *priv, struct mlx5e_rq *rq)
|
||||
{
|
||||
return (mlx5_core_modify_cq_moderation(priv->mdev, &rq->cq.mcq,
|
||||
priv->params.rx_cq_moderation_usec,
|
||||
priv->params.rx_cq_moderation_pkts));
|
||||
}
|
||||
|
||||
static int
|
||||
mlx5e_refresh_channel_params_sub(struct mlx5e_priv *priv, struct mlx5e_channel *c)
|
||||
{
|
||||
int err;
|
||||
int i;
|
||||
|
||||
if (c == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
err = mlx5e_refresh_rq_params(priv, &c->rq);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
for (i = 0; i != c->num_tc; i++) {
|
||||
err = mlx5e_refresh_sq_params(priv, &c->sq[i]);
|
||||
if (err)
|
||||
goto done;
|
||||
}
|
||||
done:
|
||||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
mlx5e_refresh_channel_params(struct mlx5e_priv *priv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (priv->channel == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
for (i = 0; i < priv->params.num_channels; i++) {
|
||||
int err;
|
||||
|
||||
err = mlx5e_refresh_channel_params_sub(priv, priv->channel[i]);
|
||||
if (err)
|
||||
return (err);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
mlx5e_open_tis(struct mlx5e_priv *priv, int tc)
|
||||
{
|
||||
@ -2298,6 +2354,7 @@ mlx5e_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
int size_read = 0;
|
||||
int module_num;
|
||||
int max_mtu;
|
||||
uint8_t read_addr;
|
||||
|
||||
priv = ifp->if_softc;
|
||||
|
||||
@ -2484,11 +2541,21 @@ mlx5e_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that we ignore i2c.addr here. The driver hardcodes
|
||||
* the address to 0x50, while standard expects it to be 0xA0.
|
||||
* Currently 0XA0 and 0xA2 are the only addresses permitted.
|
||||
* The internal conversion is as follows:
|
||||
*/
|
||||
if (i2c.dev_addr == 0xA0)
|
||||
read_addr = MLX5E_I2C_ADDR_LOW;
|
||||
else if (i2c.dev_addr == 0xA2)
|
||||
read_addr = MLX5E_I2C_ADDR_HIGH;
|
||||
else {
|
||||
if_printf(ifp, "Query eeprom failed, "
|
||||
"Invalid Address: %X\n", i2c.dev_addr);
|
||||
error = EINVAL;
|
||||
goto err_i2c;
|
||||
}
|
||||
error = mlx5_query_eeprom(priv->mdev,
|
||||
MLX5E_I2C_ADDR_LOW, MLX5E_EEPROM_LOW_PAGE,
|
||||
read_addr, MLX5E_EEPROM_LOW_PAGE,
|
||||
(uint32_t)i2c.offset, (uint32_t)i2c.len, module_num,
|
||||
(uint32_t *)i2c.data, &size_read);
|
||||
if (error) {
|
||||
@ -2499,7 +2566,7 @@ mlx5e_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
|
||||
if (i2c.len > MLX5_EEPROM_MAX_BYTES) {
|
||||
error = mlx5_query_eeprom(priv->mdev,
|
||||
MLX5E_I2C_ADDR_LOW, MLX5E_EEPROM_LOW_PAGE,
|
||||
read_addr, MLX5E_EEPROM_LOW_PAGE,
|
||||
(uint32_t)(i2c.offset + size_read),
|
||||
(uint32_t)(i2c.len - size_read), module_num,
|
||||
(uint32_t *)(i2c.data + size_read), &size_read);
|
||||
|
@ -175,6 +175,7 @@ static const STRUCT_USB_HOST_ID axe_devs[] = {
|
||||
AXE_DEV(PLANEX3, GU1000T, AXE_FLAG_178),
|
||||
AXE_DEV(SITECOM, LN029, 0),
|
||||
AXE_DEV(SITECOMEU, LN028, AXE_FLAG_178),
|
||||
AXE_DEV(SITECOMEU, LN031, AXE_FLAG_178),
|
||||
AXE_DEV(SYSTEMTALKS, SGCX2UL, 0),
|
||||
#undef AXE_DEV
|
||||
};
|
||||
|
@ -4203,6 +4203,7 @@ product SITECOMEU RTL8188CU_1 0x0052 RTL8188CU
|
||||
product SITECOMEU RTL8188CU_2 0x005c RTL8188CU
|
||||
product SITECOMEU RTL8192CU 0x0061 RTL8192CU
|
||||
product SITECOMEU LN032 0x0072 LN-032
|
||||
product SITECOMEU LN031 0x0056 LN-031
|
||||
product SITECOMEU LN028 0x061c LN-028
|
||||
product SITECOMEU WL113 0x9071 WL-113
|
||||
product SITECOMEU ZD1211B 0x9075 ZD1211B
|
||||
|
@ -568,14 +568,16 @@ static int
|
||||
null_remove(struct vop_remove_args *ap)
|
||||
{
|
||||
int retval, vreleit;
|
||||
struct vnode *lvp;
|
||||
struct vnode *lvp, *vp;
|
||||
|
||||
if (vrefcnt(ap->a_vp) > 1) {
|
||||
lvp = NULLVPTOLOWERVP(ap->a_vp);
|
||||
vp = ap->a_vp;
|
||||
if (vrefcnt(vp) > 1) {
|
||||
lvp = NULLVPTOLOWERVP(vp);
|
||||
VREF(lvp);
|
||||
vreleit = 1;
|
||||
} else
|
||||
vreleit = 0;
|
||||
VTONULL(vp)->null_flags |= NULLV_DROP;
|
||||
retval = null_bypass(&ap->a_gen);
|
||||
if (vreleit != 0)
|
||||
vrele(lvp);
|
||||
|
@ -1066,7 +1066,7 @@ fork_return(struct thread *td, struct trapframe *frame)
|
||||
cv_broadcast(&p->p_dbgwait);
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
} else if (p->p_flag & P_TRACED) {
|
||||
} else if (p->p_flag & P_TRACED || td->td_dbgflags & TDB_BORN) {
|
||||
/*
|
||||
* This is the start of a new thread in a traced
|
||||
* process. Report a system call exit event.
|
||||
@ -1074,9 +1074,10 @@ fork_return(struct thread *td, struct trapframe *frame)
|
||||
PROC_LOCK(p);
|
||||
td->td_dbgflags |= TDB_SCX;
|
||||
_STOPEVENT(p, S_SCX, td->td_dbg_sc_code);
|
||||
if ((p->p_stops & S_PT_SCX) != 0)
|
||||
if ((p->p_stops & S_PT_SCX) != 0 ||
|
||||
(td->td_dbgflags & TDB_BORN) != 0)
|
||||
ptracestop(td, SIGTRAP);
|
||||
td->td_dbgflags &= ~TDB_SCX;
|
||||
td->td_dbgflags &= ~(TDB_SCX | TDB_BORN);
|
||||
PROC_UNLOCK(p);
|
||||
}
|
||||
|
||||
|
@ -55,9 +55,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#ifdef __sparc64__
|
||||
#include <machine/ktr.h>
|
||||
#endif
|
||||
|
||||
#ifdef DDB
|
||||
#include <ddb/ddb.h>
|
||||
|
@ -2501,7 +2501,12 @@ ptracestop(struct thread *td, int sig)
|
||||
td->td_tid, p->p_pid, td->td_dbgflags, sig);
|
||||
PROC_SLOCK(p);
|
||||
while ((p->p_flag & P_TRACED) && (td->td_dbgflags & TDB_XSIG)) {
|
||||
if (p->p_flag & P_SINGLE_EXIT) {
|
||||
if (p->p_flag & P_SINGLE_EXIT &&
|
||||
!(td->td_dbgflags & TDB_EXIT)) {
|
||||
/*
|
||||
* Ignore ptrace stops except for thread exit
|
||||
* events when the process exits.
|
||||
*/
|
||||
td->td_dbgflags &= ~TDB_XSIG;
|
||||
PROC_SUNLOCK(p);
|
||||
return (sig);
|
||||
|
@ -253,6 +253,8 @@ thread_create(struct thread *td, struct rtprio *rtp,
|
||||
thread_unlock(td);
|
||||
if (P_SHOULDSTOP(p))
|
||||
newtd->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK;
|
||||
if (p->p_flag2 & P2_LWP_EVENTS)
|
||||
newtd->td_dbgflags |= TDB_BORN;
|
||||
|
||||
/*
|
||||
* Copy the existing thread VM policy into the new thread.
|
||||
@ -322,29 +324,54 @@ kern_thr_exit(struct thread *td)
|
||||
|
||||
p = td->td_proc;
|
||||
|
||||
rw_wlock(&tidhash_lock);
|
||||
/*
|
||||
* If all of the threads in a process call this routine to
|
||||
* exit (e.g. all threads call pthread_exit()), exactly one
|
||||
* thread should return to the caller to terminate the process
|
||||
* instead of the thread.
|
||||
*
|
||||
* Checking p_numthreads alone is not sufficient since threads
|
||||
* might be committed to terminating while the PROC_LOCK is
|
||||
* dropped in either ptracestop() or while removing this thread
|
||||
* from the tidhash. Instead, the p_pendingexits field holds
|
||||
* the count of threads in either of those states and a thread
|
||||
* is considered the "last" thread if all of the other threads
|
||||
* in a process are already terminating.
|
||||
*/
|
||||
PROC_LOCK(p);
|
||||
|
||||
if (p->p_numthreads != 1) {
|
||||
racct_sub(p, RACCT_NTHR, 1);
|
||||
LIST_REMOVE(td, td_hash);
|
||||
rw_wunlock(&tidhash_lock);
|
||||
tdsigcleanup(td);
|
||||
umtx_thread_exit(td);
|
||||
PROC_SLOCK(p);
|
||||
thread_stopped(p);
|
||||
thread_exit();
|
||||
/* NOTREACHED */
|
||||
if (p->p_numthreads == p->p_pendingexits + 1) {
|
||||
/*
|
||||
* Ignore attempts to shut down last thread in the
|
||||
* proc. This will actually call _exit(2) in the
|
||||
* usermode trampoline when it returns.
|
||||
*/
|
||||
PROC_UNLOCK(p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore attempts to shut down last thread in the proc. This
|
||||
* will actually call _exit(2) in the usermode trampoline when
|
||||
* it returns.
|
||||
*/
|
||||
p->p_pendingexits++;
|
||||
td->td_dbgflags |= TDB_EXIT;
|
||||
if (p->p_flag & P_TRACED && p->p_flag2 & P2_LWP_EVENTS)
|
||||
ptracestop(td, SIGTRAP);
|
||||
PROC_UNLOCK(p);
|
||||
rw_wunlock(&tidhash_lock);
|
||||
return (0);
|
||||
tidhash_remove(td);
|
||||
PROC_LOCK(p);
|
||||
p->p_pendingexits--;
|
||||
|
||||
/*
|
||||
* The check above should prevent all other threads from this
|
||||
* process from exiting while the PROC_LOCK is dropped, so
|
||||
* there must be at least one other thread other than the
|
||||
* current thread.
|
||||
*/
|
||||
KASSERT(p->p_numthreads > 1, ("too few threads"));
|
||||
racct_sub(p, RACCT_NTHR, 1);
|
||||
tdsigcleanup(td);
|
||||
umtx_thread_exit(td);
|
||||
PROC_SLOCK(p);
|
||||
thread_stopped(p);
|
||||
thread_exit();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sched.h>
|
||||
#include <sys/sleepqueue.h>
|
||||
#include <sys/selinfo.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/turnstile.h>
|
||||
#include <sys/ktr.h>
|
||||
@ -942,7 +943,6 @@ thread_suspend_check(int return_instead)
|
||||
*/
|
||||
if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td)) {
|
||||
PROC_UNLOCK(p);
|
||||
tidhash_remove(td);
|
||||
|
||||
/*
|
||||
* Allow Linux emulation layer to do some work
|
||||
@ -950,13 +950,8 @@ thread_suspend_check(int return_instead)
|
||||
*/
|
||||
if (__predict_false(p->p_sysent->sv_thread_detach != NULL))
|
||||
(p->p_sysent->sv_thread_detach)(td);
|
||||
|
||||
PROC_LOCK(p);
|
||||
tdsigcleanup(td);
|
||||
umtx_thread_exit(td);
|
||||
PROC_SLOCK(p);
|
||||
thread_stopped(p);
|
||||
thread_exit();
|
||||
kern_thr_exit(td);
|
||||
panic("stopped thread did not exit");
|
||||
}
|
||||
|
||||
PROC_SLOCK(p);
|
||||
|
@ -710,6 +710,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
||||
case PT_TO_SCX:
|
||||
case PT_SYSCALL:
|
||||
case PT_FOLLOW_FORK:
|
||||
case PT_LWP_EVENTS:
|
||||
case PT_DETACH:
|
||||
sx_xlock(&proctree_lock);
|
||||
proctree_locked = 1;
|
||||
@ -948,6 +949,16 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
||||
p->p_flag &= ~P_FOLLOWFORK;
|
||||
break;
|
||||
|
||||
case PT_LWP_EVENTS:
|
||||
CTR3(KTR_PTRACE, "PT_LWP_EVENTS: pid %d %s -> %s", p->p_pid,
|
||||
p->p_flag2 & P2_LWP_EVENTS ? "enabled" : "disabled",
|
||||
data ? "enabled" : "disabled");
|
||||
if (data)
|
||||
p->p_flag2 |= P2_LWP_EVENTS;
|
||||
else
|
||||
p->p_flag2 &= ~P2_LWP_EVENTS;
|
||||
break;
|
||||
|
||||
case PT_STEP:
|
||||
case PT_CONTINUE:
|
||||
case PT_TO_SCE:
|
||||
@ -1252,6 +1263,10 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
||||
}
|
||||
if (td2->td_dbgflags & TDB_CHILD)
|
||||
pl->pl_flags |= PL_FLAG_CHILD;
|
||||
if (td2->td_dbgflags & TDB_BORN)
|
||||
pl->pl_flags |= PL_FLAG_BORN;
|
||||
if (td2->td_dbgflags & TDB_EXIT)
|
||||
pl->pl_flags |= PL_FLAG_EXITED;
|
||||
pl->pl_sigmask = td2->td_sigmask;
|
||||
pl->pl_siglist = td2->td_siglist;
|
||||
strcpy(pl->pl_tdname, td2->td_name);
|
||||
|
@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/bpf_buffer.h>
|
||||
#ifdef BPF_JITTER
|
||||
@ -76,6 +77,7 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
#include <net/bpf_zerocopy.h>
|
||||
#include <net/bpfdesc.h>
|
||||
#include <net/route.h>
|
||||
#include <net/vnet.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
@ -164,7 +166,7 @@ static void bpf_detachd(struct bpf_d *);
|
||||
static void bpf_detachd_locked(struct bpf_d *);
|
||||
static void bpf_freed(struct bpf_d *);
|
||||
static int bpf_movein(struct uio *, int, struct ifnet *, struct mbuf **,
|
||||
struct sockaddr *, int *, struct bpf_insn *);
|
||||
struct sockaddr *, int *, struct bpf_d *);
|
||||
static int bpf_setif(struct bpf_d *, struct ifreq *);
|
||||
static void bpf_timed_out(void *);
|
||||
static __inline void
|
||||
@ -454,7 +456,7 @@ bpf_ioctl_setzbuf(struct thread *td, struct bpf_d *d, struct bpf_zbuf *bz)
|
||||
*/
|
||||
static int
|
||||
bpf_movein(struct uio *uio, int linktype, struct ifnet *ifp, struct mbuf **mp,
|
||||
struct sockaddr *sockp, int *hdrlen, struct bpf_insn *wfilter)
|
||||
struct sockaddr *sockp, int *hdrlen, struct bpf_d *d)
|
||||
{
|
||||
const struct ieee80211_bpf_params *p;
|
||||
struct ether_header *eh;
|
||||
@ -549,7 +551,7 @@ bpf_movein(struct uio *uio, int linktype, struct ifnet *ifp, struct mbuf **mp,
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
slen = bpf_filter(wfilter, mtod(m, u_char *), len, len);
|
||||
slen = bpf_filter(d->bd_wfilter, mtod(m, u_char *), len, len);
|
||||
if (slen == 0) {
|
||||
error = EPERM;
|
||||
goto bad;
|
||||
@ -566,6 +568,10 @@ bpf_movein(struct uio *uio, int linktype, struct ifnet *ifp, struct mbuf **mp,
|
||||
else
|
||||
m->m_flags |= M_MCAST;
|
||||
}
|
||||
if (d->bd_hdrcmplt == 0) {
|
||||
memcpy(eh->ether_shost, IF_LLADDR(ifp),
|
||||
sizeof(eh->ether_shost));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1088,6 +1094,7 @@ bpfwrite(struct cdev *dev, struct uio *uio, int ioflag)
|
||||
struct ifnet *ifp;
|
||||
struct mbuf *m, *mc;
|
||||
struct sockaddr dst;
|
||||
struct route ro;
|
||||
int error, hlen;
|
||||
|
||||
error = devfs_get_cdevpriv((void **)&d);
|
||||
@ -1119,7 +1126,7 @@ bpfwrite(struct cdev *dev, struct uio *uio, int ioflag)
|
||||
hlen = 0;
|
||||
/* XXX: bpf_movein() can sleep */
|
||||
error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, ifp,
|
||||
&m, &dst, &hlen, d->bd_wfilter);
|
||||
&m, &dst, &hlen, d);
|
||||
if (error) {
|
||||
d->bd_wdcount++;
|
||||
return (error);
|
||||
@ -1151,7 +1158,14 @@ bpfwrite(struct cdev *dev, struct uio *uio, int ioflag)
|
||||
BPFD_UNLOCK(d);
|
||||
#endif
|
||||
|
||||
error = (*ifp->if_output)(ifp, m, &dst, NULL);
|
||||
bzero(&ro, sizeof(ro));
|
||||
if (hlen != 0) {
|
||||
ro.ro_prepend = (u_char *)&dst.sa_data;
|
||||
ro.ro_plen = hlen;
|
||||
ro.ro_flags = RT_HAS_HEADER;
|
||||
}
|
||||
|
||||
error = (*ifp->if_output)(ifp, m, &dst, &ro);
|
||||
if (error)
|
||||
d->bd_wdcount++;
|
||||
|
||||
|
@ -665,6 +665,7 @@ int
|
||||
flowtable_lookup(sa_family_t sa, struct mbuf *m, struct route *ro)
|
||||
{
|
||||
struct flentry *fle;
|
||||
struct llentry *lle;
|
||||
|
||||
if (V_flowtable_enable == 0)
|
||||
return (ENXIO);
|
||||
@ -693,8 +694,15 @@ flowtable_lookup(sa_family_t sa, struct mbuf *m, struct route *ro)
|
||||
}
|
||||
|
||||
ro->ro_rt = fle->f_rt;
|
||||
ro->ro_lle = fle->f_lle;
|
||||
ro->ro_flags |= RT_NORTREF;
|
||||
lle = fle->f_lle;
|
||||
if (lle != NULL && (lle->la_flags & LLE_VALID)) {
|
||||
ro->ro_prepend = lle->r_linkdata;
|
||||
ro->ro_plen = lle->r_hdrlen;
|
||||
ro->ro_flags |= RT_MAY_LOOP;
|
||||
if (lle->la_flags & LLE_IFADDR)
|
||||
ro->ro_flags |= RT_L2_ME;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
41
sys/net/if.c
41
sys/net/if.c
@ -161,6 +161,7 @@ static int ifconf(u_long, caddr_t);
|
||||
static void if_freemulti(struct ifmultiaddr *);
|
||||
static void if_grow(void);
|
||||
static void if_input_default(struct ifnet *, struct mbuf *);
|
||||
static int if_requestencap_default(struct ifnet *, struct if_encap_req *);
|
||||
static void if_route(struct ifnet *, int flag, int fam);
|
||||
static int if_setflag(struct ifnet *, int, int, int *, int);
|
||||
static int if_transmit(struct ifnet *ifp, struct mbuf *m);
|
||||
@ -673,6 +674,9 @@ if_attach_internal(struct ifnet *ifp, int vmove, struct if_clone *ifc)
|
||||
if (ifp->if_input == NULL)
|
||||
ifp->if_input = if_input_default;
|
||||
|
||||
if (ifp->if_requestencap == NULL)
|
||||
ifp->if_requestencap = if_requestencap_default;
|
||||
|
||||
if (!vmove) {
|
||||
#ifdef MAC
|
||||
mac_ifnet_create(ifp);
|
||||
@ -3397,6 +3401,43 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compat function for handling basic encapsulation requests.
|
||||
* Not converted stacks (FDDI, IB, ..) supports traditional
|
||||
* output model: ARP (and other similar L2 protocols) are handled
|
||||
* inside output routine, arpresolve/nd6_resolve() returns MAC
|
||||
* address instead of full prepend.
|
||||
*
|
||||
* This function creates calculated header==MAC for IPv4/IPv6 and
|
||||
* returns EAFNOSUPPORT (which is then handled in ARP code) for other
|
||||
* address families.
|
||||
*/
|
||||
static int
|
||||
if_requestencap_default(struct ifnet *ifp, struct if_encap_req *req)
|
||||
{
|
||||
|
||||
if (req->rtype != IFENCAP_LL)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
if (req->bufsize < req->lladdr_len)
|
||||
return (ENOMEM);
|
||||
|
||||
switch (req->family) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
break;
|
||||
default:
|
||||
return (EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
/* Copy lladdr to storage as is */
|
||||
memmove(req->buf, req->lladdr, req->lladdr_len);
|
||||
req->bufsize = req->lladdr_len;
|
||||
req->lladdr_off = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The name argument must be a pointer to storage which will last as
|
||||
* long as the interface does. For physical devices, the result of
|
||||
|
@ -113,6 +113,7 @@ static int ether_resolvemulti(struct ifnet *, struct sockaddr **,
|
||||
#ifdef VIMAGE
|
||||
static void ether_reassign(struct ifnet *, struct vnet *, char *);
|
||||
#endif
|
||||
static int ether_requestencap(struct ifnet *, struct if_encap_req *);
|
||||
|
||||
#define ETHER_IS_BROADCAST(addr) \
|
||||
(bcmp(etherbroadcastaddr, (addr), ETHER_ADDR_LEN) == 0)
|
||||
@ -135,6 +136,138 @@ update_mbuf_csumflags(struct mbuf *src, struct mbuf *dst)
|
||||
dst->m_pkthdr.csum_data = 0xffff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle link-layer encapsulation requests.
|
||||
*/
|
||||
static int
|
||||
ether_requestencap(struct ifnet *ifp, struct if_encap_req *req)
|
||||
{
|
||||
struct ether_header *eh;
|
||||
struct arphdr *ah;
|
||||
uint16_t etype;
|
||||
const u_char *lladdr;
|
||||
|
||||
if (req->rtype != IFENCAP_LL)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
if (req->bufsize < ETHER_HDR_LEN)
|
||||
return (ENOMEM);
|
||||
|
||||
eh = (struct ether_header *)req->buf;
|
||||
lladdr = req->lladdr;
|
||||
req->lladdr_off = 0;
|
||||
|
||||
switch (req->family) {
|
||||
case AF_INET:
|
||||
etype = htons(ETHERTYPE_IP);
|
||||
break;
|
||||
case AF_INET6:
|
||||
etype = htons(ETHERTYPE_IPV6);
|
||||
break;
|
||||
case AF_ARP:
|
||||
ah = (struct arphdr *)req->hdata;
|
||||
ah->ar_hrd = htons(ARPHRD_ETHER);
|
||||
|
||||
switch(ntohs(ah->ar_op)) {
|
||||
case ARPOP_REVREQUEST:
|
||||
case ARPOP_REVREPLY:
|
||||
etype = htons(ETHERTYPE_REVARP);
|
||||
break;
|
||||
case ARPOP_REQUEST:
|
||||
case ARPOP_REPLY:
|
||||
default:
|
||||
etype = htons(ETHERTYPE_ARP);
|
||||
break;
|
||||
}
|
||||
|
||||
if (req->flags & IFENCAP_FLAG_BROADCAST)
|
||||
lladdr = ifp->if_broadcastaddr;
|
||||
break;
|
||||
default:
|
||||
return (EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
memcpy(&eh->ether_type, &etype, sizeof(eh->ether_type));
|
||||
memcpy(eh->ether_dhost, lladdr, ETHER_ADDR_LEN);
|
||||
memcpy(eh->ether_shost, IF_LLADDR(ifp), ETHER_ADDR_LEN);
|
||||
req->bufsize = sizeof(struct ether_header);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ether_resolve_addr(struct ifnet *ifp, struct mbuf *m,
|
||||
const struct sockaddr *dst, struct route *ro, u_char *phdr,
|
||||
uint32_t *pflags)
|
||||
{
|
||||
struct ether_header *eh;
|
||||
struct rtentry *rt;
|
||||
uint32_t lleflags = 0;
|
||||
int error = 0;
|
||||
#if defined(INET) || defined(INET6)
|
||||
uint16_t etype;
|
||||
#endif
|
||||
|
||||
eh = (struct ether_header *)phdr;
|
||||
|
||||
switch (dst->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if ((m->m_flags & (M_BCAST | M_MCAST)) == 0)
|
||||
error = arpresolve(ifp, 0, m, dst, phdr, &lleflags);
|
||||
else {
|
||||
if (m->m_flags & M_BCAST)
|
||||
memcpy(eh->ether_dhost, ifp->if_broadcastaddr,
|
||||
ETHER_ADDR_LEN);
|
||||
else {
|
||||
const struct in_addr *a;
|
||||
a = &(((const struct sockaddr_in *)dst)->sin_addr);
|
||||
ETHER_MAP_IP_MULTICAST(a, eh->ether_dhost);
|
||||
}
|
||||
etype = htons(ETHERTYPE_IP);
|
||||
memcpy(&eh->ether_type, &etype, sizeof(etype));
|
||||
memcpy(eh->ether_shost, IF_LLADDR(ifp), ETHER_ADDR_LEN);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if ((m->m_flags & M_MCAST) == 0)
|
||||
error = nd6_resolve(ifp, 0, m, dst, phdr, &lleflags);
|
||||
else {
|
||||
const struct in6_addr *a6;
|
||||
a6 = &(((const struct sockaddr_in6 *)dst)->sin6_addr);
|
||||
ETHER_MAP_IPV6_MULTICAST(a6, eh->ether_dhost);
|
||||
etype = htons(ETHERTYPE_IPV6);
|
||||
memcpy(&eh->ether_type, &etype, sizeof(etype));
|
||||
memcpy(eh->ether_shost, IF_LLADDR(ifp), ETHER_ADDR_LEN);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if_printf(ifp, "can't handle af%d\n", dst->sa_family);
|
||||
if (m != NULL)
|
||||
m_freem(m);
|
||||
return (EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
if (error == EHOSTDOWN) {
|
||||
rt = (ro != NULL) ? ro->ro_rt : NULL;
|
||||
if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) != 0)
|
||||
error = EHOSTUNREACH;
|
||||
}
|
||||
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
*pflags = RT_MAY_LOOP;
|
||||
if (lleflags & LLE_IFADDR)
|
||||
*pflags |= RT_L2_ME;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ethernet output routine.
|
||||
* Encapsulate a packet of type family for the local net.
|
||||
@ -145,27 +278,20 @@ int
|
||||
ether_output(struct ifnet *ifp, struct mbuf *m,
|
||||
const struct sockaddr *dst, struct route *ro)
|
||||
{
|
||||
short type;
|
||||
int error = 0, hdrcmplt = 0;
|
||||
u_char edst[ETHER_ADDR_LEN];
|
||||
struct llentry *lle = NULL;
|
||||
struct rtentry *rt0 = NULL;
|
||||
int error = 0;
|
||||
char linkhdr[ETHER_HDR_LEN], *phdr;
|
||||
struct ether_header *eh;
|
||||
struct pf_mtag *t;
|
||||
int loop_copy = 1;
|
||||
int hlen; /* link layer header length */
|
||||
int is_gw = 0;
|
||||
uint32_t pflags = 0;
|
||||
uint32_t pflags;
|
||||
|
||||
phdr = NULL;
|
||||
pflags = 0;
|
||||
if (ro != NULL) {
|
||||
if (!(m->m_flags & (M_BCAST | M_MCAST))) {
|
||||
lle = ro->ro_lle;
|
||||
if (lle != NULL)
|
||||
pflags = lle->la_flags;
|
||||
}
|
||||
rt0 = ro->ro_rt;
|
||||
if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0)
|
||||
is_gw = 1;
|
||||
phdr = ro->ro_prepend;
|
||||
hlen = ro->ro_plen;
|
||||
pflags = ro->ro_flags;
|
||||
}
|
||||
#ifdef MAC
|
||||
error = mac_ifnet_check_transmit(ifp, m);
|
||||
@ -180,94 +306,31 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
|
||||
senderr(ENETDOWN);
|
||||
|
||||
hlen = ETHER_HDR_LEN;
|
||||
switch (dst->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (lle != NULL && (pflags & LLE_VALID) != 0)
|
||||
memcpy(edst, &lle->ll_addr.mac16, sizeof(edst));
|
||||
else
|
||||
error = arpresolve(ifp, is_gw, m, dst, edst, &pflags);
|
||||
if (error)
|
||||
if (phdr == NULL) {
|
||||
/* No prepend data supplied. Try to calculate ourselves. */
|
||||
phdr = linkhdr;
|
||||
hlen = ETHER_HDR_LEN;
|
||||
error = ether_resolve_addr(ifp, m, dst, ro, phdr, &pflags);
|
||||
if (error != 0)
|
||||
return (error == EWOULDBLOCK ? 0 : error);
|
||||
type = htons(ETHERTYPE_IP);
|
||||
break;
|
||||
case AF_ARP:
|
||||
{
|
||||
struct arphdr *ah;
|
||||
ah = mtod(m, struct arphdr *);
|
||||
ah->ar_hrd = htons(ARPHRD_ETHER);
|
||||
|
||||
loop_copy = 0; /* if this is for us, don't do it */
|
||||
|
||||
switch(ntohs(ah->ar_op)) {
|
||||
case ARPOP_REVREQUEST:
|
||||
case ARPOP_REVREPLY:
|
||||
type = htons(ETHERTYPE_REVARP);
|
||||
break;
|
||||
case ARPOP_REQUEST:
|
||||
case ARPOP_REPLY:
|
||||
default:
|
||||
type = htons(ETHERTYPE_ARP);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m->m_flags & M_BCAST)
|
||||
bcopy(ifp->if_broadcastaddr, edst, ETHER_ADDR_LEN);
|
||||
else
|
||||
bcopy(ar_tha(ah), edst, ETHER_ADDR_LEN);
|
||||
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (lle != NULL && (pflags & LLE_VALID))
|
||||
memcpy(edst, &lle->ll_addr.mac16, sizeof(edst));
|
||||
else
|
||||
error = nd6_resolve(ifp, is_gw, m, dst, (u_char *)edst,
|
||||
&pflags);
|
||||
if (error)
|
||||
return (error == EWOULDBLOCK ? 0 : error);
|
||||
type = htons(ETHERTYPE_IPV6);
|
||||
break;
|
||||
#endif
|
||||
case pseudo_AF_HDRCMPLT:
|
||||
{
|
||||
const struct ether_header *eh;
|
||||
|
||||
hdrcmplt = 1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case AF_UNSPEC:
|
||||
loop_copy = 0; /* if this is for us, don't do it */
|
||||
eh = (const struct ether_header *)dst->sa_data;
|
||||
(void)memcpy(edst, eh->ether_dhost, sizeof (edst));
|
||||
type = eh->ether_type;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if_printf(ifp, "can't handle af%d\n", dst->sa_family);
|
||||
senderr(EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
if ((pflags & LLE_IFADDR) != 0) {
|
||||
if ((pflags & RT_L2_ME) != 0) {
|
||||
update_mbuf_csumflags(m, m);
|
||||
return (if_simloop(ifp, m, dst->sa_family, 0));
|
||||
}
|
||||
loop_copy = pflags & RT_MAY_LOOP;
|
||||
|
||||
/*
|
||||
* Add local net header. If no space in first mbuf,
|
||||
* allocate another.
|
||||
*/
|
||||
M_PREPEND(m, ETHER_HDR_LEN, M_NOWAIT);
|
||||
M_PREPEND(m, hlen, M_NOWAIT);
|
||||
if (m == NULL)
|
||||
senderr(ENOBUFS);
|
||||
eh = mtod(m, struct ether_header *);
|
||||
if (hdrcmplt == 0) {
|
||||
memcpy(&eh->ether_type, &type, sizeof(eh->ether_type));
|
||||
memcpy(eh->ether_dhost, edst, sizeof (edst));
|
||||
memcpy(eh->ether_shost, IF_LLADDR(ifp),sizeof(eh->ether_shost));
|
||||
if ((pflags & RT_HAS_HEADER) == 0) {
|
||||
eh = mtod(m, struct ether_header *);
|
||||
memcpy(eh, phdr, hlen);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -279,34 +342,27 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
|
||||
* on the wire). However, we don't do that here for security
|
||||
* reasons and compatibility with the original behavior.
|
||||
*/
|
||||
if ((ifp->if_flags & IFF_SIMPLEX) && loop_copy &&
|
||||
if ((m->m_flags & M_BCAST) && loop_copy && (ifp->if_flags & IFF_SIMPLEX) &&
|
||||
((t = pf_find_mtag(m)) == NULL || !t->routed)) {
|
||||
if (m->m_flags & M_BCAST) {
|
||||
struct mbuf *n;
|
||||
struct mbuf *n;
|
||||
|
||||
/*
|
||||
* Because if_simloop() modifies the packet, we need a
|
||||
* writable copy through m_dup() instead of a readonly
|
||||
* one as m_copy[m] would give us. The alternative would
|
||||
* be to modify if_simloop() to handle the readonly mbuf,
|
||||
* but performancewise it is mostly equivalent (trading
|
||||
* extra data copying vs. extra locking).
|
||||
*
|
||||
* XXX This is a local workaround. A number of less
|
||||
* often used kernel parts suffer from the same bug.
|
||||
* See PR kern/105943 for a proposed general solution.
|
||||
*/
|
||||
if ((n = m_dup(m, M_NOWAIT)) != NULL) {
|
||||
update_mbuf_csumflags(m, n);
|
||||
(void)if_simloop(ifp, n, dst->sa_family, hlen);
|
||||
} else
|
||||
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
|
||||
} else if (bcmp(eh->ether_dhost, eh->ether_shost,
|
||||
ETHER_ADDR_LEN) == 0) {
|
||||
update_mbuf_csumflags(m, m);
|
||||
(void) if_simloop(ifp, m, dst->sa_family, hlen);
|
||||
return (0); /* XXX */
|
||||
}
|
||||
/*
|
||||
* Because if_simloop() modifies the packet, we need a
|
||||
* writable copy through m_dup() instead of a readonly
|
||||
* one as m_copy[m] would give us. The alternative would
|
||||
* be to modify if_simloop() to handle the readonly mbuf,
|
||||
* but performancewise it is mostly equivalent (trading
|
||||
* extra data copying vs. extra locking).
|
||||
*
|
||||
* XXX This is a local workaround. A number of less
|
||||
* often used kernel parts suffer from the same bug.
|
||||
* See PR kern/105943 for a proposed general solution.
|
||||
*/
|
||||
if ((n = m_dup(m, M_NOWAIT)) != NULL) {
|
||||
update_mbuf_csumflags(m, n);
|
||||
(void)if_simloop(ifp, n, dst->sa_family, hlen);
|
||||
} else
|
||||
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -798,6 +854,7 @@ ether_ifattach(struct ifnet *ifp, const u_int8_t *lla)
|
||||
ifp->if_output = ether_output;
|
||||
ifp->if_input = ether_input;
|
||||
ifp->if_resolvemulti = ether_resolvemulti;
|
||||
ifp->if_requestencap = ether_requestencap;
|
||||
#ifdef VIMAGE
|
||||
ifp->if_reassign = ether_reassign;
|
||||
#endif
|
||||
|
@ -529,7 +529,6 @@ gif_input(struct mbuf *m, struct ifnet *ifp, int proto, uint8_t ecn)
|
||||
struct gif_softc *sc;
|
||||
struct ether_header *eh;
|
||||
struct ifnet *oldifp;
|
||||
uint32_t gif_options;
|
||||
int isr, n, af;
|
||||
|
||||
if (ifp == NULL) {
|
||||
@ -538,7 +537,6 @@ gif_input(struct mbuf *m, struct ifnet *ifp, int proto, uint8_t ecn)
|
||||
return;
|
||||
}
|
||||
sc = ifp->if_softc;
|
||||
gif_options = sc->gif_options;
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
m_clrprotoflags(m);
|
||||
switch (proto) {
|
||||
|
@ -682,7 +682,10 @@ gre_input(struct mbuf **mp, int *offp, int proto)
|
||||
struct grehdr *gh;
|
||||
struct ifnet *ifp;
|
||||
struct mbuf *m;
|
||||
uint32_t *opts, key;
|
||||
uint32_t *opts;
|
||||
#ifdef notyet
|
||||
uint32_t key;
|
||||
#endif
|
||||
uint16_t flags;
|
||||
int hlen, isr, af;
|
||||
|
||||
@ -715,17 +718,28 @@ gre_input(struct mbuf **mp, int *offp, int proto)
|
||||
opts++;
|
||||
}
|
||||
if (flags & GRE_FLAGS_KP) {
|
||||
#ifdef notyet
|
||||
/*
|
||||
* XXX: The current implementation uses the key only for outgoing
|
||||
* packets. But we can check the key value here, or even in the
|
||||
* encapcheck function.
|
||||
*/
|
||||
key = ntohl(*opts);
|
||||
#endif
|
||||
hlen += sizeof(uint32_t);
|
||||
opts++;
|
||||
}
|
||||
#ifdef notyet
|
||||
} else
|
||||
key = 0;
|
||||
/*
|
||||
|
||||
if (sc->gre_key != 0 && (key != sc->gre_key || key != 0))
|
||||
goto drop;
|
||||
*/
|
||||
#endif
|
||||
if (flags & GRE_FLAGS_SP) {
|
||||
/* seq = ntohl(*opts); */
|
||||
#ifdef notyet
|
||||
seq = ntohl(*opts);
|
||||
#endif
|
||||
hlen += sizeof(uint32_t);
|
||||
}
|
||||
switch (ntohs(gh->gre_proto)) {
|
||||
|
@ -278,10 +278,12 @@ lltable_drop_entry_queue(struct llentry *lle)
|
||||
|
||||
void
|
||||
lltable_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
|
||||
const char *lladdr)
|
||||
const char *linkhdr, size_t linkhdrsize, int lladdr_off)
|
||||
{
|
||||
|
||||
bcopy(lladdr, &lle->ll_addr, ifp->if_addrlen);
|
||||
memcpy(lle->r_linkdata, linkhdr, linkhdrsize);
|
||||
lle->r_hdrlen = linkhdrsize;
|
||||
lle->ll_addr = &lle->r_linkdata[lladdr_off];
|
||||
lle->la_flags |= LLE_VALID;
|
||||
lle->r_flags |= RLLE_VALID;
|
||||
}
|
||||
@ -296,7 +298,7 @@ lltable_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
|
||||
*/
|
||||
int
|
||||
lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
|
||||
const char *lladdr)
|
||||
const char *linkhdr, size_t linkhdrsize, int lladdr_off)
|
||||
{
|
||||
|
||||
/* Perform real LLE update */
|
||||
@ -318,7 +320,7 @@ lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
|
||||
}
|
||||
|
||||
/* Update data */
|
||||
lltable_set_entry_addr(ifp, lle, lladdr);
|
||||
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize, lladdr_off);
|
||||
|
||||
IF_AFDATA_WUNLOCK(ifp);
|
||||
|
||||
@ -327,6 +329,84 @@ lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function used to pre-compute full/partial link-layer
|
||||
* header data suitable for feeding into if_output().
|
||||
*/
|
||||
int
|
||||
lltable_calc_llheader(struct ifnet *ifp, int family, char *lladdr,
|
||||
char *buf, size_t *bufsize, int *lladdr_off)
|
||||
{
|
||||
struct if_encap_req ereq;
|
||||
int error;
|
||||
|
||||
bzero(buf, *bufsize);
|
||||
bzero(&ereq, sizeof(ereq));
|
||||
ereq.buf = buf;
|
||||
ereq.bufsize = *bufsize;
|
||||
ereq.rtype = IFENCAP_LL;
|
||||
ereq.family = family;
|
||||
ereq.lladdr = lladdr;
|
||||
ereq.lladdr_len = ifp->if_addrlen;
|
||||
error = ifp->if_requestencap(ifp, &ereq);
|
||||
if (error == 0) {
|
||||
*bufsize = ereq.bufsize;
|
||||
*lladdr_off = ereq.lladdr_off;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update link-layer header for given @lle after
|
||||
* interface lladdr was changed.
|
||||
*/
|
||||
static int
|
||||
llentry_update_ifaddr(struct lltable *llt, struct llentry *lle, void *farg)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
u_char linkhdr[LLE_MAX_LINKHDR];
|
||||
size_t linkhdrsize;
|
||||
u_char *lladdr;
|
||||
int lladdr_off;
|
||||
|
||||
ifp = (struct ifnet *)farg;
|
||||
|
||||
lladdr = lle->ll_addr;
|
||||
|
||||
LLE_WLOCK(lle);
|
||||
if ((lle->la_flags & LLE_VALID) == 0) {
|
||||
LLE_WUNLOCK(lle);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((lle->la_flags & LLE_IFADDR) != 0)
|
||||
lladdr = IF_LLADDR(ifp);
|
||||
|
||||
linkhdrsize = sizeof(linkhdr);
|
||||
lltable_calc_llheader(ifp, llt->llt_af, lladdr, linkhdr, &linkhdrsize,
|
||||
&lladdr_off);
|
||||
memcpy(lle->r_linkdata, linkhdr, linkhdrsize);
|
||||
LLE_WUNLOCK(lle);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update all calculated headers for given @llt
|
||||
*/
|
||||
void
|
||||
lltable_update_ifaddr(struct lltable *llt)
|
||||
{
|
||||
|
||||
if (llt->llt_ifp->if_flags & IFF_LOOPBACK)
|
||||
return;
|
||||
|
||||
IF_AFDATA_WLOCK(llt->llt_ifp);
|
||||
lltable_foreach_lle(llt, llentry_update_ifaddr, llt->llt_ifp);
|
||||
IF_AFDATA_WUNLOCK(llt->llt_ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Performes generic cleanup routines and frees lle.
|
||||
@ -642,6 +722,9 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
|
||||
struct ifnet *ifp;
|
||||
struct lltable *llt;
|
||||
struct llentry *lle, *lle_tmp;
|
||||
uint8_t linkhdr[LLE_MAX_LINKHDR];
|
||||
size_t linkhdrsize;
|
||||
int lladdr_off;
|
||||
u_int laflags = 0;
|
||||
int error;
|
||||
|
||||
@ -677,11 +760,14 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
|
||||
if (lle == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bcopy(LLADDR(dl), &lle->ll_addr, ifp->if_addrlen);
|
||||
linkhdrsize = sizeof(linkhdr);
|
||||
if (lltable_calc_llheader(ifp, dst->sa_family, LLADDR(dl),
|
||||
linkhdr, &linkhdrsize, &lladdr_off) != 0)
|
||||
return (EINVAL);
|
||||
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
|
||||
lladdr_off);
|
||||
if ((rtm->rtm_flags & RTF_ANNOUNCE))
|
||||
lle->la_flags |= LLE_PUB;
|
||||
lle->la_flags |= LLE_VALID;
|
||||
lle->r_flags |= RLLE_VALID;
|
||||
lle->la_expire = rtm->rtm_rmx.rmx_expire;
|
||||
|
||||
laflags = lle->la_flags;
|
||||
@ -767,7 +853,7 @@ llatbl_lle_show(struct llentry_sa *la)
|
||||
db_printf(" ln_router=%u\n", lle->ln_router);
|
||||
db_printf(" ln_ntick=%ju\n", (uintmax_t)lle->ln_ntick);
|
||||
db_printf(" lle_refcnt=%d\n", lle->lle_refcnt);
|
||||
bcopy(&lle->ll_addr.mac16, octet, sizeof(octet));
|
||||
bcopy(lle->ll_addr, octet, sizeof(octet));
|
||||
db_printf(" ll_addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
octet[0], octet[1], octet[2], octet[3], octet[4], octet[5]);
|
||||
db_printf(" lle_timer=%p\n", &lle->lle_timer);
|
||||
|
@ -48,6 +48,7 @@ extern struct rwlock lltable_rwlock;
|
||||
#define LLTABLE_WUNLOCK() rw_wunlock(&lltable_rwlock)
|
||||
#define LLTABLE_LOCK_ASSERT() rw_assert(&lltable_rwlock, RA_LOCKED)
|
||||
|
||||
#define LLE_MAX_LINKHDR 24 /* Full IB header */
|
||||
/*
|
||||
* Code referencing llentry must at least hold
|
||||
* a shared lock
|
||||
@ -58,14 +59,11 @@ struct llentry {
|
||||
struct in_addr addr4;
|
||||
struct in6_addr addr6;
|
||||
} r_l3addr;
|
||||
union {
|
||||
uint64_t mac_aligned;
|
||||
uint16_t mac16[3];
|
||||
uint8_t mac8[20]; /* IB needs 20 bytes. */
|
||||
} ll_addr;
|
||||
char r_linkdata[LLE_MAX_LINKHDR]; /* L2 data */
|
||||
uint8_t r_hdrlen; /* length for LL header */
|
||||
uint8_t spare0[3];
|
||||
uint16_t r_flags; /* LLE runtime flags */
|
||||
uint16_t r_skip_req; /* feedback from fast path */
|
||||
uint64_t spare1;
|
||||
|
||||
struct lltable *lle_tbl;
|
||||
struct llentries *lle_head;
|
||||
@ -82,6 +80,7 @@ struct llentry {
|
||||
time_t lle_remtime; /* Real time remaining */
|
||||
time_t lle_hittime; /* Time when r_skip_req was unset */
|
||||
int lle_refcnt;
|
||||
char *ll_addr; /* link-layer address */
|
||||
|
||||
LIST_ENTRY(llentry) lle_chain; /* chain of deleted items */
|
||||
struct callout lle_timer;
|
||||
@ -198,6 +197,8 @@ MALLOC_DECLARE(M_LLTABLE);
|
||||
/* LLE request flags */
|
||||
#define LLE_EXCLUSIVE 0x2000 /* return lle xlocked */
|
||||
#define LLE_UNLOCKED 0x4000 /* return lle unlocked */
|
||||
#define LLE_ADDRONLY 0x4000 /* return lladdr instead of full header */
|
||||
#define LLE_CREATE 0x8000 /* hint to avoid lle lookup */
|
||||
|
||||
/* LLE flags used by fastpath code */
|
||||
#define RLLE_VALID 0x0001 /* entry is valid */
|
||||
@ -223,10 +224,13 @@ struct llentry *llentry_alloc(struct ifnet *, struct lltable *,
|
||||
/* helper functions */
|
||||
size_t lltable_drop_entry_queue(struct llentry *);
|
||||
void lltable_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
|
||||
const char *lladdr);
|
||||
const char *linkhdr, size_t linkhdrsize, int lladdr_off);
|
||||
int lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
|
||||
const char *lladdr);
|
||||
const char *linkhdr, size_t linkhdrsize, int lladdr_off);
|
||||
|
||||
int lltable_calc_llheader(struct ifnet *ifp, int family, char *lladdr,
|
||||
char *buf, size_t *bufsize, int *lladdr_off);
|
||||
void lltable_update_ifaddr(struct lltable *llt);
|
||||
struct llentry *lltable_alloc_entry(struct lltable *llt, u_int flags,
|
||||
const struct sockaddr *l4addr);
|
||||
void lltable_free_entry(struct lltable *llt, struct llentry *lle);
|
||||
|
@ -134,6 +134,48 @@ struct ifnet_hw_tsomax {
|
||||
u_int tsomaxsegsize; /* TSO maximum segment size in bytes */
|
||||
};
|
||||
|
||||
/* Interface encap request types */
|
||||
typedef enum {
|
||||
IFENCAP_LL = 1 /* pre-calculate link-layer header */
|
||||
} ife_type;
|
||||
|
||||
/*
|
||||
* The structure below allows to request various pre-calculated L2/L3 headers
|
||||
* for different media. Requests varies by type (rtype field).
|
||||
*
|
||||
* IFENCAP_LL type: pre-calculates link header based on address family
|
||||
* and destination lladdr.
|
||||
*
|
||||
* Input data fields:
|
||||
* buf: pointer to destination buffer
|
||||
* bufsize: buffer size
|
||||
* flags: IFENCAP_FLAG_BROADCAST if destination is broadcast
|
||||
* family: address family defined by AF_ constant.
|
||||
* lladdr: pointer to link-layer address
|
||||
* lladdr_len: length of link-layer address
|
||||
* hdata: pointer to L3 header (optional, used for ARP requests).
|
||||
* Output data fields:
|
||||
* buf: encap data is stored here
|
||||
* bufsize: resulting encap length is stored here
|
||||
* lladdr_off: offset of link-layer address from encap hdr start
|
||||
* hdata: L3 header may be altered if necessary
|
||||
*/
|
||||
|
||||
struct if_encap_req {
|
||||
u_char *buf; /* Destination buffer (w) */
|
||||
size_t bufsize; /* size of provided buffer (r) */
|
||||
ife_type rtype; /* request type (r) */
|
||||
uint32_t flags; /* Request flags (r) */
|
||||
int family; /* Address family AF_* (r) */
|
||||
int lladdr_off; /* offset from header start (w) */
|
||||
int lladdr_len; /* lladdr length (r) */
|
||||
char *lladdr; /* link-level address pointer (r) */
|
||||
char *hdata; /* Upper layer header data (rw) */
|
||||
};
|
||||
|
||||
#define IFENCAP_FLAG_BROADCAST 0x02 /* Destination is broadcast */
|
||||
|
||||
|
||||
/*
|
||||
* Structure defining a network interface.
|
||||
*
|
||||
@ -235,6 +277,8 @@ struct ifnet {
|
||||
void (*if_reassign) /* reassign to vnet routine */
|
||||
(struct ifnet *, struct vnet *, char *);
|
||||
if_get_counter_t if_get_counter; /* get counter values */
|
||||
int (*if_requestencap) /* make link header from request */
|
||||
(struct ifnet *, struct if_encap_req *);
|
||||
|
||||
/* Statistics. */
|
||||
counter_u64_t if_counters[IFCOUNTERS];
|
||||
|
@ -51,14 +51,21 @@
|
||||
*/
|
||||
struct route {
|
||||
struct rtentry *ro_rt;
|
||||
struct llentry *ro_lle;
|
||||
struct in_ifaddr *ro_ia;
|
||||
int ro_flags;
|
||||
char *ro_prepend;
|
||||
uint16_t ro_plen;
|
||||
uint16_t ro_flags;
|
||||
struct sockaddr ro_dst;
|
||||
};
|
||||
|
||||
#define RT_L2_ME_BIT 2 /* dst L2 addr is our address */
|
||||
#define RT_MAY_LOOP_BIT 3 /* dst may require loop copy */
|
||||
#define RT_HAS_HEADER_BIT 4 /* mbuf already have its header prepended */
|
||||
|
||||
#define RT_CACHING_CONTEXT 0x1 /* XXX: not used anywhere */
|
||||
#define RT_NORTREF 0x2 /* doesn't hold reference on ro_rt */
|
||||
#define RT_L2_ME (1 << RT_L2_ME_BIT)
|
||||
#define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT)
|
||||
#define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT)
|
||||
|
||||
struct rt_metrics {
|
||||
u_long rmx_locks; /* Kernel must leave these values alone */
|
||||
|
@ -281,6 +281,37 @@ arptimer(void *arg)
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
|
||||
/*
|
||||
* Stores link-layer header for @ifp in format suitable for if_output()
|
||||
* into buffer @buf. Resulting header length is stored in @bufsize.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
static int
|
||||
arp_fillheader(struct ifnet *ifp, struct arphdr *ah, int bcast, u_char *buf,
|
||||
size_t *bufsize)
|
||||
{
|
||||
struct if_encap_req ereq;
|
||||
int error;
|
||||
|
||||
bzero(buf, *bufsize);
|
||||
bzero(&ereq, sizeof(ereq));
|
||||
ereq.buf = buf;
|
||||
ereq.bufsize = *bufsize;
|
||||
ereq.rtype = IFENCAP_LL;
|
||||
ereq.family = AF_ARP;
|
||||
ereq.lladdr = ar_tha(ah);
|
||||
ereq.hdata = (u_char *)ah;
|
||||
if (bcast)
|
||||
ereq.flags = IFENCAP_FLAG_BROADCAST;
|
||||
error = ifp->if_requestencap(ifp, &ereq);
|
||||
if (error == 0)
|
||||
*bufsize = ereq.bufsize;
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Broadcast an ARP request. Caller specifies:
|
||||
* - arp header source ip address
|
||||
@ -295,6 +326,10 @@ arprequest(struct ifnet *ifp, const struct in_addr *sip,
|
||||
struct arphdr *ah;
|
||||
struct sockaddr sa;
|
||||
u_char *carpaddr = NULL;
|
||||
uint8_t linkhdr[LLE_MAX_LINKHDR];
|
||||
size_t linkhdrsize;
|
||||
struct route ro;
|
||||
int error;
|
||||
|
||||
if (sip == NULL) {
|
||||
/*
|
||||
@ -350,12 +385,28 @@ arprequest(struct ifnet *ifp, const struct in_addr *sip,
|
||||
bcopy(tip, ar_tpa(ah), ah->ar_pln);
|
||||
sa.sa_family = AF_ARP;
|
||||
sa.sa_len = 2;
|
||||
|
||||
/* Calculate link header for sending frame */
|
||||
bzero(&ro, sizeof(ro));
|
||||
linkhdrsize = sizeof(linkhdr);
|
||||
error = arp_fillheader(ifp, ah, 1, linkhdr, &linkhdrsize);
|
||||
if (error != 0 && error != EAFNOSUPPORT) {
|
||||
ARP_LOG(LOG_ERR, "Failed to calculate ARP header on %s: %d\n",
|
||||
if_name(ifp), error);
|
||||
return;
|
||||
}
|
||||
|
||||
ro.ro_prepend = linkhdr;
|
||||
ro.ro_plen = linkhdrsize;
|
||||
ro.ro_flags = 0;
|
||||
|
||||
m->m_flags |= M_BCAST;
|
||||
m_clrprotoflags(m); /* Avoid confusing lower layers. */
|
||||
(*ifp->if_output)(ifp, m, &sa, NULL);
|
||||
(*ifp->if_output)(ifp, m, &sa, &ro);
|
||||
ARPSTAT_INC(txrequests);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Resolve an IP address into an ethernet address - heavy version.
|
||||
* Used internally by arpresolve().
|
||||
@ -368,18 +419,20 @@ arprequest(struct ifnet *ifp, const struct in_addr *sip,
|
||||
* Note that m_freem() handles NULL.
|
||||
*/
|
||||
static int
|
||||
arpresolve_full(struct ifnet *ifp, int is_gw, int create, struct mbuf *m,
|
||||
arpresolve_full(struct ifnet *ifp, int is_gw, int flags, struct mbuf *m,
|
||||
const struct sockaddr *dst, u_char *desten, uint32_t *pflags)
|
||||
{
|
||||
struct llentry *la = NULL, *la_tmp;
|
||||
struct mbuf *curr = NULL;
|
||||
struct mbuf *next = NULL;
|
||||
int error, renew;
|
||||
char *lladdr;
|
||||
int ll_len;
|
||||
|
||||
if (pflags != NULL)
|
||||
*pflags = 0;
|
||||
|
||||
if (create == 0) {
|
||||
if ((flags & LLE_CREATE) == 0) {
|
||||
IF_AFDATA_RLOCK(ifp);
|
||||
la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
|
||||
IF_AFDATA_RUNLOCK(ifp);
|
||||
@ -413,7 +466,14 @@ arpresolve_full(struct ifnet *ifp, int is_gw, int create, struct mbuf *m,
|
||||
|
||||
if ((la->la_flags & LLE_VALID) &&
|
||||
((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) {
|
||||
bcopy(&la->ll_addr, desten, ifp->if_addrlen);
|
||||
if (flags & LLE_ADDRONLY) {
|
||||
lladdr = la->ll_addr;
|
||||
ll_len = ifp->if_addrlen;
|
||||
} else {
|
||||
lladdr = la->r_linkdata;
|
||||
ll_len = la->r_hdrlen;
|
||||
}
|
||||
bcopy(lladdr, desten, ll_len);
|
||||
|
||||
/* Check if we have feedback request from arptimer() */
|
||||
if (la->r_skip_req != 0) {
|
||||
@ -485,15 +545,31 @@ arpresolve_full(struct ifnet *ifp, int is_gw, int create, struct mbuf *m,
|
||||
|
||||
/*
|
||||
* Resolve an IP address into an ethernet address.
|
||||
*/
|
||||
int
|
||||
arpresolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst,
|
||||
char *desten, uint32_t *pflags)
|
||||
{
|
||||
int error;
|
||||
|
||||
flags |= LLE_ADDRONLY;
|
||||
error = arpresolve_full(ifp, 0, flags, NULL, dst, desten, pflags);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Lookups link header based on an IP address.
|
||||
* On input:
|
||||
* ifp is the interface we use
|
||||
* is_gw != 0 if @dst represents gateway to some destination
|
||||
* m is the mbuf. May be NULL if we don't have a packet.
|
||||
* dst is the next hop,
|
||||
* desten is the storage to put LL address.
|
||||
* desten is the storage to put LL header.
|
||||
* flags returns subset of lle flags: LLE_VALID | LLE_IFADDR
|
||||
*
|
||||
* On success, desten and flags are filled in and the function returns 0;
|
||||
* On success, full/partial link header and flags are filled in and
|
||||
* the function returns 0.
|
||||
* If the packet must be held pending resolution, we return EWOULDBLOCK
|
||||
* On other errors, we return the corresponding error code.
|
||||
* Note that m_freem() handles NULL.
|
||||
@ -525,7 +601,7 @@ arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
|
||||
la = lla_lookup(LLTABLE(ifp), LLE_UNLOCKED, dst);
|
||||
if (la != NULL && (la->r_flags & RLLE_VALID) != 0) {
|
||||
/* Entry found, let's copy lle info */
|
||||
bcopy(&la->ll_addr, desten, ifp->if_addrlen);
|
||||
bcopy(la->r_linkdata, desten, la->r_hdrlen);
|
||||
if (pflags != NULL)
|
||||
*pflags = LLE_VALID | (la->r_flags & RLLE_IFADDR);
|
||||
/* Check if we have feedback request from arptimer() */
|
||||
@ -539,7 +615,8 @@ arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
|
||||
}
|
||||
IF_AFDATA_RUNLOCK(ifp);
|
||||
|
||||
return (arpresolve_full(ifp, is_gw, 1, m, dst, desten, pflags));
|
||||
return (arpresolve_full(ifp, is_gw, la == NULL ? LLE_CREATE : 0, m, dst,
|
||||
desten, pflags));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -683,6 +760,11 @@ in_arpinput(struct mbuf *m)
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr *dst;
|
||||
struct nhop4_basic nh4;
|
||||
uint8_t linkhdr[LLE_MAX_LINKHDR];
|
||||
struct route ro;
|
||||
size_t linkhdrsize;
|
||||
int lladdr_off;
|
||||
int error;
|
||||
|
||||
sin.sin_len = sizeof(struct sockaddr_in);
|
||||
sin.sin_family = AF_INET;
|
||||
@ -850,8 +932,14 @@ in_arpinput(struct mbuf *m)
|
||||
else if (itaddr.s_addr == myaddr.s_addr) {
|
||||
/*
|
||||
* Request/reply to our address, but no lle exists yet.
|
||||
* Try to create new llentry.
|
||||
* Calculate full link prepend to use in lle.
|
||||
*/
|
||||
linkhdrsize = sizeof(linkhdr);
|
||||
if (lltable_calc_llheader(ifp, AF_INET, ar_sha(ah), linkhdr,
|
||||
&linkhdrsize, &lladdr_off) != 0)
|
||||
goto reply;
|
||||
|
||||
/* Allocate new entry */
|
||||
la = lltable_alloc_entry(LLTABLE(ifp), 0, dst);
|
||||
if (la == NULL) {
|
||||
|
||||
@ -863,7 +951,8 @@ in_arpinput(struct mbuf *m)
|
||||
*/
|
||||
goto reply;
|
||||
}
|
||||
lltable_set_entry_addr(ifp, la, ar_sha(ah));
|
||||
lltable_set_entry_addr(ifp, la, linkhdr, linkhdrsize,
|
||||
lladdr_off);
|
||||
|
||||
IF_AFDATA_WLOCK(ifp);
|
||||
LLE_WLOCK(la);
|
||||
@ -921,7 +1010,7 @@ in_arpinput(struct mbuf *m)
|
||||
|
||||
if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
|
||||
(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
|
||||
(void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln);
|
||||
(void)memcpy(ar_sha(ah), lle->ll_addr, ah->ar_hln);
|
||||
LLE_RUNLOCK(lle);
|
||||
} else {
|
||||
|
||||
@ -991,8 +1080,29 @@ in_arpinput(struct mbuf *m)
|
||||
m->m_pkthdr.rcvif = NULL;
|
||||
sa.sa_family = AF_ARP;
|
||||
sa.sa_len = 2;
|
||||
|
||||
/* Calculate link header for sending frame */
|
||||
bzero(&ro, sizeof(ro));
|
||||
linkhdrsize = sizeof(linkhdr);
|
||||
error = arp_fillheader(ifp, ah, 0, linkhdr, &linkhdrsize);
|
||||
|
||||
/*
|
||||
* arp_fillheader() may fail due to lack of support inside encap request
|
||||
* routing. This is not necessary an error, AF_ARP can/should be handled
|
||||
* by if_output().
|
||||
*/
|
||||
if (error != 0 && error != EAFNOSUPPORT) {
|
||||
ARP_LOG(LOG_ERR, "Failed to calculate ARP header on %s: %d\n",
|
||||
if_name(ifp), error);
|
||||
return;
|
||||
}
|
||||
|
||||
ro.ro_prepend = linkhdr;
|
||||
ro.ro_plen = linkhdrsize;
|
||||
ro.ro_flags = 0;
|
||||
|
||||
m_clrprotoflags(m); /* Avoid confusing lower layers. */
|
||||
(*ifp->if_output)(ifp, m, &sa, NULL);
|
||||
(*ifp->if_output)(ifp, m, &sa, &ro);
|
||||
ARPSTAT_INC(txreplies);
|
||||
return;
|
||||
|
||||
@ -1011,6 +1121,9 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp
|
||||
{
|
||||
struct sockaddr sa;
|
||||
struct mbuf *m_hold, *m_hold_next;
|
||||
uint8_t linkhdr[LLE_MAX_LINKHDR];
|
||||
size_t linkhdrsize;
|
||||
int lladdr_off;
|
||||
|
||||
LLE_WLOCK_ASSERT(la);
|
||||
|
||||
@ -1027,7 +1140,7 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp
|
||||
return;
|
||||
}
|
||||
if ((la->la_flags & LLE_VALID) &&
|
||||
bcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) {
|
||||
bcmp(ar_sha(ah), la->ll_addr, ifp->if_addrlen)) {
|
||||
if (la->la_flags & LLE_STATIC) {
|
||||
LLE_WUNLOCK(la);
|
||||
if (log_arp_permanent_modify)
|
||||
@ -1050,31 +1163,19 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate full link prepend to use in lle */
|
||||
linkhdrsize = sizeof(linkhdr);
|
||||
if (lltable_calc_llheader(ifp, AF_INET, ar_sha(ah), linkhdr,
|
||||
&linkhdrsize, &lladdr_off) != 0)
|
||||
return;
|
||||
|
||||
/* Check if something has changed */
|
||||
if (memcmp(&la->ll_addr, ar_sha(ah), ifp->if_addrlen) != 0 ||
|
||||
if (memcmp(la->r_linkdata, linkhdr, linkhdrsize) != 0 ||
|
||||
(la->la_flags & LLE_VALID) == 0) {
|
||||
/* Perform real LLE update */
|
||||
/* use afdata WLOCK to update fields */
|
||||
LLE_ADDREF(la);
|
||||
LLE_WUNLOCK(la);
|
||||
IF_AFDATA_WLOCK(ifp);
|
||||
LLE_WLOCK(la);
|
||||
|
||||
/*
|
||||
* Since we droppped LLE lock, other thread might have deleted
|
||||
* this lle. Check and return
|
||||
*/
|
||||
if ((la->la_flags & LLE_DELETED) != 0) {
|
||||
IF_AFDATA_WUNLOCK(ifp);
|
||||
LLE_FREE_LOCKED(la);
|
||||
/* Try to perform LLE update */
|
||||
if (lltable_try_set_entry_addr(ifp, la, linkhdr, linkhdrsize,
|
||||
lladdr_off) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update data */
|
||||
lltable_set_entry_addr(ifp, la, ar_sha(ah));
|
||||
|
||||
IF_AFDATA_WUNLOCK(ifp);
|
||||
LLE_REMREF(la);
|
||||
|
||||
/* Clear fast path feedback request if set */
|
||||
la->r_skip_req = 0;
|
||||
@ -1215,10 +1316,12 @@ arp_handle_ifllchange(struct ifnet *ifp)
|
||||
/*
|
||||
* A handler for interface link layer address change event.
|
||||
*/
|
||||
static __noinline void
|
||||
static void
|
||||
arp_iflladdr(void *arg __unused, struct ifnet *ifp)
|
||||
{
|
||||
|
||||
lltable_update_ifaddr(LLTABLE(ifp));
|
||||
|
||||
if ((ifp->if_flags & IFF_UP) != 0)
|
||||
arp_handle_ifllchange(ifp);
|
||||
}
|
||||
@ -1231,5 +1334,8 @@ arp_init(void)
|
||||
if (IS_DEFAULT_VNET(curvnet))
|
||||
iflladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event,
|
||||
arp_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
|
||||
if (IS_DEFAULT_VNET(curvnet))
|
||||
iflladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event,
|
||||
arp_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
|
||||
}
|
||||
SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0);
|
||||
|
@ -114,6 +114,8 @@ extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN];
|
||||
|
||||
struct ifaddr;
|
||||
|
||||
int arpresolve_addr(struct ifnet *ifp, int flags,
|
||||
const struct sockaddr *dst, char *desten, uint32_t *pflags);
|
||||
int arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
|
||||
const struct sockaddr *dst, u_char *desten, uint32_t *pflags);
|
||||
void arprequest(struct ifnet *, const struct in_addr *,
|
||||
|
@ -1240,6 +1240,9 @@ in_lltable_alloc(struct lltable *llt, u_int flags, const struct sockaddr *l3addr
|
||||
const struct sockaddr_in *sin = (const struct sockaddr_in *)l3addr;
|
||||
struct ifnet *ifp = llt->llt_ifp;
|
||||
struct llentry *lle;
|
||||
char linkhdr[LLE_MAX_LINKHDR];
|
||||
size_t linkhdrsize;
|
||||
int lladdr_off;
|
||||
|
||||
KASSERT(l3addr->sa_family == AF_INET,
|
||||
("sin_family %d", l3addr->sa_family));
|
||||
@ -1262,7 +1265,12 @@ in_lltable_alloc(struct lltable *llt, u_int flags, const struct sockaddr *l3addr
|
||||
if (flags & LLE_STATIC)
|
||||
lle->r_flags |= RLLE_VALID;
|
||||
if ((flags & LLE_IFADDR) == LLE_IFADDR) {
|
||||
lltable_set_entry_addr(ifp, lle, IF_LLADDR(ifp));
|
||||
linkhdrsize = LLE_MAX_LINKHDR;
|
||||
if (lltable_calc_llheader(ifp, AF_INET, IF_LLADDR(ifp),
|
||||
linkhdr, &linkhdrsize, &lladdr_off) != 0)
|
||||
return (NULL);
|
||||
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
|
||||
lladdr_off);
|
||||
lle->la_flags |= LLE_STATIC;
|
||||
lle->r_flags |= (RLLE_VALID | RLLE_IFADDR);
|
||||
}
|
||||
@ -1349,7 +1357,7 @@ in_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
|
||||
sdl->sdl_type = ifp->if_type;
|
||||
if ((lle->la_flags & LLE_VALID) == LLE_VALID) {
|
||||
sdl->sdl_alen = ifp->if_addrlen;
|
||||
bcopy(&lle->ll_addr, LLADDR(sdl), ifp->if_addrlen);
|
||||
bcopy(lle->ll_addr, LLADDR(sdl), ifp->if_addrlen);
|
||||
} else {
|
||||
sdl->sdl_alen = 0;
|
||||
bzero(LLADDR(sdl), ifp->if_addrlen);
|
||||
|
@ -567,7 +567,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
RO_RTFREE(ro);
|
||||
if (have_ia_ref)
|
||||
ifa_free(&ia->ia_ifa);
|
||||
ro->ro_lle = NULL;
|
||||
ro->ro_prepend = NULL;
|
||||
rte = NULL;
|
||||
gw = dst;
|
||||
ip = mtod(m, struct ip *);
|
||||
|
@ -428,7 +428,7 @@ toe_lle_event(void *arg __unused, struct llentry *lle, int evt)
|
||||
KASSERT(lle->la_flags & LLE_VALID,
|
||||
("%s: %p resolved but not valid?", __func__, lle));
|
||||
|
||||
lladdr = (uint8_t *)&lle->ll_addr;
|
||||
lladdr = (uint8_t *)lle->ll_addr;
|
||||
#ifdef VLAN_TAG
|
||||
VLAN_TAG(ifp, &vtag);
|
||||
#endif
|
||||
|
@ -2632,7 +2632,7 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt)
|
||||
nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
|
||||
nd_opt->nd_opt_len = len >> 3;
|
||||
lladdr = (char *)(nd_opt + 1);
|
||||
bcopy(&ln->ll_addr, lladdr, ifp->if_addrlen);
|
||||
bcopy(ln->ll_addr, lladdr, ifp->if_addrlen);
|
||||
p += len;
|
||||
}
|
||||
}
|
||||
|
@ -1552,7 +1552,7 @@ in6ifa_llaonifp(struct ifnet *ifp)
|
||||
|
||||
if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)
|
||||
return (NULL);
|
||||
if_addr_rlock(ifp);
|
||||
IF_ADDR_RLOCK(ifp);
|
||||
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
||||
if (ifa->ifa_addr->sa_family != AF_INET6)
|
||||
continue;
|
||||
@ -1562,7 +1562,7 @@ in6ifa_llaonifp(struct ifnet *ifp)
|
||||
IN6_IS_ADDR_MC_NODELOCAL(&sin6->sin6_addr))
|
||||
break;
|
||||
}
|
||||
if_addr_runlock(ifp);
|
||||
IF_ADDR_RUNLOCK(ifp);
|
||||
|
||||
return ((struct in6_ifaddr *)ifa);
|
||||
}
|
||||
@ -2245,6 +2245,9 @@ in6_lltable_alloc(struct lltable *llt, u_int flags,
|
||||
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)l3addr;
|
||||
struct ifnet *ifp = llt->llt_ifp;
|
||||
struct llentry *lle;
|
||||
char linkhdr[LLE_MAX_LINKHDR];
|
||||
size_t linkhdrsize;
|
||||
int lladdr_off;
|
||||
|
||||
KASSERT(l3addr->sa_family == AF_INET6,
|
||||
("sin_family %d", l3addr->sa_family));
|
||||
@ -2265,7 +2268,12 @@ in6_lltable_alloc(struct lltable *llt, u_int flags,
|
||||
}
|
||||
lle->la_flags = flags;
|
||||
if ((flags & LLE_IFADDR) == LLE_IFADDR) {
|
||||
lltable_set_entry_addr(ifp, lle, IF_LLADDR(ifp));
|
||||
linkhdrsize = LLE_MAX_LINKHDR;
|
||||
if (lltable_calc_llheader(ifp, AF_INET6, IF_LLADDR(ifp),
|
||||
linkhdr, &linkhdrsize, &lladdr_off) != 0)
|
||||
return (NULL);
|
||||
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
|
||||
lladdr_off);
|
||||
lle->la_flags |= LLE_STATIC;
|
||||
}
|
||||
|
||||
|
@ -375,9 +375,9 @@ extern const struct in6_addr in6addr_linklocal_allv2routers;
|
||||
#if __BSD_VISIBLE
|
||||
struct route_in6 {
|
||||
struct rtentry *ro_rt;
|
||||
struct llentry *ro_lle;
|
||||
struct in6_addr *ro_ia6;
|
||||
int ro_flags;
|
||||
char *ro_prepend;
|
||||
uint16_t ro_plen;
|
||||
uint16_t ro_flags;
|
||||
struct sockaddr_in6 ro_dst;
|
||||
};
|
||||
#endif
|
||||
|
@ -1830,6 +1830,7 @@ do { \
|
||||
case IPV6_RSSBUCKETID:
|
||||
case IPV6_RECVRSSBUCKETID:
|
||||
#endif
|
||||
case IPV6_BINDMULTI:
|
||||
switch (optname) {
|
||||
|
||||
case IPV6_RECVHOPOPTS:
|
||||
|
@ -111,7 +111,7 @@ VNET_DEFINE(int, nd6_debug) = 1;
|
||||
VNET_DEFINE(int, nd6_debug) = 0;
|
||||
#endif
|
||||
|
||||
static eventhandler_tag lle_event_eh;
|
||||
static eventhandler_tag lle_event_eh, iflladdr_event_eh;
|
||||
|
||||
/* for debugging? */
|
||||
#if 0
|
||||
@ -137,7 +137,7 @@ static void nd6_llinfo_timer(void *);
|
||||
static void nd6_llinfo_settimer_locked(struct llentry *, long);
|
||||
static void clear_llinfo_pqueue(struct llentry *);
|
||||
static void nd6_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
|
||||
static int nd6_resolve_slow(struct ifnet *, struct mbuf *,
|
||||
static int nd6_resolve_slow(struct ifnet *, int, struct mbuf *,
|
||||
const struct sockaddr_in6 *, u_char *, uint32_t *);
|
||||
static int nd6_need_cache(struct ifnet *);
|
||||
|
||||
@ -188,7 +188,7 @@ nd6_lle_event(void *arg __unused, struct llentry *lle, int evt)
|
||||
gw.sdl_index = ifp->if_index;
|
||||
gw.sdl_type = ifp->if_type;
|
||||
if (evt == LLENTRY_RESOLVED)
|
||||
bcopy(&lle->ll_addr, gw.sdl_data, ifp->if_addrlen);
|
||||
bcopy(lle->ll_addr, gw.sdl_data, ifp->if_addrlen);
|
||||
rtinfo.rti_info[RTAX_DST] = (struct sockaddr *)&dst;
|
||||
rtinfo.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gw;
|
||||
rtinfo.rti_addrs = RTA_DST | RTA_GATEWAY;
|
||||
@ -196,6 +196,16 @@ nd6_lle_event(void *arg __unused, struct llentry *lle, int evt)
|
||||
type == RTM_ADD ? RTF_UP: 0), 0, RT_DEFAULT_FIB);
|
||||
}
|
||||
|
||||
/*
|
||||
* A handler for interface link layer address change event.
|
||||
*/
|
||||
static void
|
||||
nd6_iflladdr(void *arg __unused, struct ifnet *ifp)
|
||||
{
|
||||
|
||||
lltable_update_ifaddr(LLTABLE6(ifp));
|
||||
}
|
||||
|
||||
void
|
||||
nd6_init(void)
|
||||
{
|
||||
@ -211,9 +221,12 @@ nd6_init(void)
|
||||
nd6_slowtimo, curvnet);
|
||||
|
||||
nd6_dad_init();
|
||||
if (IS_DEFAULT_VNET(curvnet))
|
||||
if (IS_DEFAULT_VNET(curvnet)) {
|
||||
lle_event_eh = EVENTHANDLER_REGISTER(lle_event, nd6_lle_event,
|
||||
NULL, EVENTHANDLER_PRI_ANY);
|
||||
iflladdr_event_eh = EVENTHANDLER_REGISTER(iflladdr_event,
|
||||
nd6_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VIMAGE
|
||||
@ -223,8 +236,10 @@ nd6_destroy()
|
||||
|
||||
callout_drain(&V_nd6_slowtimo_ch);
|
||||
callout_drain(&V_nd6_timer_ch);
|
||||
if (IS_DEFAULT_VNET(curvnet))
|
||||
if (IS_DEFAULT_VNET(curvnet)) {
|
||||
EVENTHANDLER_DEREGISTER(lle_event, lle_event_eh);
|
||||
EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_event_eh);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1844,6 +1859,9 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
|
||||
uint16_t router = 0;
|
||||
struct sockaddr_in6 sin6;
|
||||
struct mbuf *chain = NULL;
|
||||
u_char linkhdr[LLE_MAX_LINKHDR];
|
||||
size_t linkhdrsize;
|
||||
int lladdr_off;
|
||||
|
||||
IF_AFDATA_UNLOCK_ASSERT(ifp);
|
||||
|
||||
@ -1878,8 +1896,15 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
|
||||
* Since we already know all the data for the new entry,
|
||||
* fill it before insertion.
|
||||
*/
|
||||
if (lladdr != NULL)
|
||||
lltable_set_entry_addr(ifp, ln, lladdr);
|
||||
if (lladdr != NULL) {
|
||||
linkhdrsize = sizeof(linkhdr);
|
||||
if (lltable_calc_llheader(ifp, AF_INET6, lladdr,
|
||||
linkhdr, &linkhdrsize, &lladdr_off) != 0)
|
||||
return;
|
||||
lltable_set_entry_addr(ifp, ln, linkhdr, linkhdrsize,
|
||||
lladdr_off);
|
||||
}
|
||||
|
||||
IF_AFDATA_WLOCK(ifp);
|
||||
LLE_WLOCK(ln);
|
||||
/* Prefer any existing lle over newly-created one */
|
||||
@ -1911,7 +1936,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
|
||||
|
||||
olladdr = (ln->la_flags & LLE_VALID) ? 1 : 0;
|
||||
if (olladdr && lladdr) {
|
||||
llchange = bcmp(lladdr, &ln->ll_addr,
|
||||
llchange = bcmp(lladdr, ln->ll_addr,
|
||||
ifp->if_addrlen);
|
||||
} else if (!olladdr && lladdr)
|
||||
llchange = 1;
|
||||
@ -1937,7 +1962,13 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
|
||||
* Record source link-layer address
|
||||
* XXX is it dependent to ifp->if_type?
|
||||
*/
|
||||
if (lltable_try_set_entry_addr(ifp, ln, lladdr) == 0) {
|
||||
linkhdrsize = sizeof(linkhdr);
|
||||
if (lltable_calc_llheader(ifp, AF_INET6, lladdr,
|
||||
linkhdr, &linkhdrsize, &lladdr_off) != 0)
|
||||
return;
|
||||
|
||||
if (lltable_try_set_entry_addr(ifp, ln, linkhdr, linkhdrsize,
|
||||
lladdr_off) == 0) {
|
||||
/* Entry was deleted */
|
||||
return;
|
||||
}
|
||||
@ -2093,8 +2124,8 @@ nd6_output_ifp(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m,
|
||||
}
|
||||
|
||||
/*
|
||||
* Do L2 address resolution for @sa_dst address. Stores found
|
||||
* address in @desten buffer. Copy of lle ln_flags can be also
|
||||
* Lookup link headerfor @sa_dst address. Stores found
|
||||
* data in @desten buffer. Copy of lle ln_flags can be also
|
||||
* saved in @pflags if @pflags is non-NULL.
|
||||
*
|
||||
* If destination LLE does not exists or lle state modification
|
||||
@ -2144,7 +2175,7 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
|
||||
ln = nd6_lookup(&dst6->sin6_addr, LLE_UNLOCKED, ifp);
|
||||
if (ln != NULL && (ln->r_flags & RLLE_VALID) != 0) {
|
||||
/* Entry found, let's copy lle info */
|
||||
bcopy(&ln->ll_addr, desten, ifp->if_addrlen);
|
||||
bcopy(ln->r_linkdata, desten, ln->r_hdrlen);
|
||||
if (pflags != NULL)
|
||||
*pflags = LLE_VALID | (ln->r_flags & RLLE_IFADDR);
|
||||
/* Check if we have feedback request from nd6 timer */
|
||||
@ -2159,7 +2190,7 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
|
||||
}
|
||||
IF_AFDATA_RUNLOCK(ifp);
|
||||
|
||||
return (nd6_resolve_slow(ifp, m, dst6, desten, pflags));
|
||||
return (nd6_resolve_slow(ifp, 0, m, dst6, desten, pflags));
|
||||
}
|
||||
|
||||
|
||||
@ -2175,12 +2206,13 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
|
||||
* Set noinline to be dtrace-friendly
|
||||
*/
|
||||
static __noinline int
|
||||
nd6_resolve_slow(struct ifnet *ifp, struct mbuf *m,
|
||||
nd6_resolve_slow(struct ifnet *ifp, int flags, struct mbuf *m,
|
||||
const struct sockaddr_in6 *dst, u_char *desten, uint32_t *pflags)
|
||||
{
|
||||
struct llentry *lle = NULL, *lle_tmp;
|
||||
struct in6_addr *psrc, src;
|
||||
int send_ns;
|
||||
int send_ns, ll_len;
|
||||
char *lladdr;
|
||||
|
||||
/*
|
||||
* Address resolution or Neighbor Unreachability Detection
|
||||
@ -2252,7 +2284,14 @@ nd6_resolve_slow(struct ifnet *ifp, struct mbuf *m,
|
||||
* send the packet.
|
||||
*/
|
||||
if (lle->ln_state > ND6_LLINFO_INCOMPLETE) {
|
||||
bcopy(&lle->ll_addr, desten, ifp->if_addrlen);
|
||||
if (flags & LLE_ADDRONLY) {
|
||||
lladdr = lle->ll_addr;
|
||||
ll_len = ifp->if_addrlen;
|
||||
} else {
|
||||
lladdr = lle->r_linkdata;
|
||||
ll_len = lle->r_hdrlen;
|
||||
}
|
||||
bcopy(lladdr, desten, ll_len);
|
||||
if (pflags != NULL)
|
||||
*pflags = lle->la_flags;
|
||||
LLE_WUNLOCK(lle);
|
||||
@ -2312,6 +2351,27 @@ nd6_resolve_slow(struct ifnet *ifp, struct mbuf *m,
|
||||
return (EWOULDBLOCK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do L2 address resolution for @sa_dst address. Stores found
|
||||
* address in @desten buffer. Copy of lle ln_flags can be also
|
||||
* saved in @pflags if @pflags is non-NULL.
|
||||
*
|
||||
* Return values:
|
||||
* - 0 on success (address copied to buffer).
|
||||
* - EWOULDBLOCK (no local error, but address is still unresolved)
|
||||
* - other errors (alloc failure, etc)
|
||||
*/
|
||||
int
|
||||
nd6_resolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst,
|
||||
char *desten, uint32_t *pflags)
|
||||
{
|
||||
int error;
|
||||
|
||||
flags |= LLE_ADDRONLY;
|
||||
error = nd6_resolve_slow(ifp, flags, NULL,
|
||||
(const struct sockaddr_in6 *)dst, desten, pflags);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
nd6_flush_holdchain(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *chain,
|
||||
|
@ -410,6 +410,8 @@ void nd6_setmtu(struct ifnet *);
|
||||
void nd6_llinfo_setstate(struct llentry *lle, int newstate);
|
||||
void nd6_timer(void *);
|
||||
void nd6_purge(struct ifnet *);
|
||||
int nd6_resolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst,
|
||||
char *desten, uint32_t *pflags);
|
||||
int nd6_resolve(struct ifnet *, int, struct mbuf *,
|
||||
const struct sockaddr *, u_char *, uint32_t *);
|
||||
int nd6_ioctl(u_long, caddr_t, struct ifnet *);
|
||||
|
@ -643,6 +643,9 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
|
||||
union nd_opts ndopts;
|
||||
struct mbuf *chain = NULL;
|
||||
struct sockaddr_in6 sin6;
|
||||
u_char linkhdr[LLE_MAX_LINKHDR];
|
||||
size_t linkhdrsize;
|
||||
int lladdr_off;
|
||||
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
|
||||
|
||||
if (ip6->ip6_hlim != 255) {
|
||||
@ -765,7 +768,13 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
|
||||
/*
|
||||
* Record link-layer address, and update the state.
|
||||
*/
|
||||
if (lltable_try_set_entry_addr(ifp, ln, lladdr) == 0) {
|
||||
linkhdrsize = sizeof(linkhdr);
|
||||
if (lltable_calc_llheader(ifp, AF_INET6, lladdr,
|
||||
linkhdr, &linkhdrsize, &lladdr_off) != 0)
|
||||
return;
|
||||
|
||||
if (lltable_try_set_entry_addr(ifp, ln, linkhdr, linkhdrsize,
|
||||
lladdr_off) == 0) {
|
||||
ln = NULL;
|
||||
goto freeit;
|
||||
}
|
||||
@ -792,7 +801,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
|
||||
llchange = 0;
|
||||
else {
|
||||
if (ln->la_flags & LLE_VALID) {
|
||||
if (bcmp(lladdr, &ln->ll_addr, ifp->if_addrlen))
|
||||
if (bcmp(lladdr, ln->ll_addr, ifp->if_addrlen))
|
||||
llchange = 1;
|
||||
else
|
||||
llchange = 0;
|
||||
@ -834,9 +843,12 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
|
||||
* Update link-local address, if any.
|
||||
*/
|
||||
if (lladdr != NULL) {
|
||||
int ret;
|
||||
ret = lltable_try_set_entry_addr(ifp, ln,lladdr);
|
||||
if (ret == 0) {
|
||||
linkhdrsize = sizeof(linkhdr);
|
||||
if (lltable_calc_llheader(ifp, AF_INET6, lladdr,
|
||||
linkhdr, &linkhdrsize, &lladdr_off) != 0)
|
||||
goto freeit;
|
||||
if (lltable_try_set_entry_addr(ifp, ln, linkhdr,
|
||||
linkhdrsize, lladdr_off) == 0) {
|
||||
ln = NULL;
|
||||
goto freeit;
|
||||
}
|
||||
|
@ -1257,15 +1257,15 @@ ipoib_output(struct ifnet *ifp, struct mbuf *m,
|
||||
const struct sockaddr *dst, struct route *ro)
|
||||
{
|
||||
u_char edst[INFINIBAND_ALEN];
|
||||
#if defined(INET) || defined(INET6)
|
||||
struct llentry *lle = NULL;
|
||||
#endif
|
||||
struct rtentry *rt0 = NULL;
|
||||
struct ipoib_header *eh;
|
||||
int error = 0, is_gw = 0;
|
||||
short type;
|
||||
|
||||
if (ro != NULL) {
|
||||
if (!(m->m_flags & (M_BCAST | M_MCAST)))
|
||||
lle = ro->ro_lle;
|
||||
rt0 = ro->ro_rt;
|
||||
if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0)
|
||||
is_gw = 1;
|
||||
@ -1291,7 +1291,7 @@ ipoib_output(struct ifnet *ifp, struct mbuf *m,
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (lle != NULL && (lle->la_flags & LLE_VALID))
|
||||
memcpy(edst, &lle->ll_addr.mac8, sizeof(edst));
|
||||
memcpy(edst, lle->ll_addr, sizeof(edst));
|
||||
else if (m->m_flags & M_MCAST)
|
||||
ip_ib_mc_map(((struct sockaddr_in *)dst)->sin_addr.s_addr, ifp->if_broadcastaddr, edst);
|
||||
else
|
||||
@ -1329,7 +1329,7 @@ ipoib_output(struct ifnet *ifp, struct mbuf *m,
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (lle != NULL && (lle->la_flags & LLE_VALID))
|
||||
memcpy(edst, &lle->ll_addr.mac8, sizeof(edst));
|
||||
memcpy(edst, lle->ll_addr, sizeof(edst));
|
||||
else if (m->m_flags & M_MCAST)
|
||||
ipv6_ib_mc_map(&((struct sockaddr_in6 *)dst)->sin6_addr, ifp->if_broadcastaddr, edst);
|
||||
else
|
||||
|
@ -14,6 +14,11 @@
|
||||
* 29 May 1998
|
||||
*/
|
||||
|
||||
#ifndef _SKIPJACK_H_
|
||||
#define _SKIPJACK_H_
|
||||
|
||||
extern void skipjack_forwards(u_int8_t *plain, u_int8_t *cipher, u_int8_t **key);
|
||||
extern void skipjack_backwards(u_int8_t *cipher, u_int8_t *plain, u_int8_t **key);
|
||||
extern void subkey_table_gen(u_int8_t *key, u_int8_t **key_tables);
|
||||
|
||||
#endif
|
||||
|
@ -75,196 +75,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <opencrypto/cryptodev.h>
|
||||
#include <opencrypto/xform.h>
|
||||
|
||||
static int null_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static int des1_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static int des3_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static int blf_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static int cast5_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static int skipjack_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static int rijndael128_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static int aes_icm_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static int aes_xts_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static int cml_setkey(u_int8_t **, u_int8_t *, int);
|
||||
|
||||
static void null_encrypt(caddr_t, u_int8_t *);
|
||||
static void des1_encrypt(caddr_t, u_int8_t *);
|
||||
static void des3_encrypt(caddr_t, u_int8_t *);
|
||||
static void blf_encrypt(caddr_t, u_int8_t *);
|
||||
static void cast5_encrypt(caddr_t, u_int8_t *);
|
||||
static void skipjack_encrypt(caddr_t, u_int8_t *);
|
||||
static void rijndael128_encrypt(caddr_t, u_int8_t *);
|
||||
static void aes_xts_encrypt(caddr_t, u_int8_t *);
|
||||
static void cml_encrypt(caddr_t, u_int8_t *);
|
||||
|
||||
static void null_decrypt(caddr_t, u_int8_t *);
|
||||
static void des1_decrypt(caddr_t, u_int8_t *);
|
||||
static void des3_decrypt(caddr_t, u_int8_t *);
|
||||
static void blf_decrypt(caddr_t, u_int8_t *);
|
||||
static void cast5_decrypt(caddr_t, u_int8_t *);
|
||||
static void skipjack_decrypt(caddr_t, u_int8_t *);
|
||||
static void rijndael128_decrypt(caddr_t, u_int8_t *);
|
||||
static void aes_xts_decrypt(caddr_t, u_int8_t *);
|
||||
static void cml_decrypt(caddr_t, u_int8_t *);
|
||||
|
||||
static void aes_icm_crypt(caddr_t, u_int8_t *);
|
||||
|
||||
static void null_zerokey(u_int8_t **);
|
||||
static void des1_zerokey(u_int8_t **);
|
||||
static void des3_zerokey(u_int8_t **);
|
||||
static void blf_zerokey(u_int8_t **);
|
||||
static void cast5_zerokey(u_int8_t **);
|
||||
static void skipjack_zerokey(u_int8_t **);
|
||||
static void rijndael128_zerokey(u_int8_t **);
|
||||
static void aes_icm_zerokey(u_int8_t **);
|
||||
static void aes_xts_zerokey(u_int8_t **);
|
||||
static void cml_zerokey(u_int8_t **);
|
||||
|
||||
static void aes_icm_reinit(caddr_t, u_int8_t *);
|
||||
static void aes_xts_reinit(caddr_t, u_int8_t *);
|
||||
static void aes_gcm_reinit(caddr_t, u_int8_t *);
|
||||
|
||||
static void null_init(void *);
|
||||
static void null_reinit(void *ctx, const u_int8_t *buf, u_int16_t len);
|
||||
static int null_update(void *, const u_int8_t *, u_int16_t);
|
||||
static void null_final(u_int8_t *, void *);
|
||||
static int MD5Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
static void SHA1Init_int(void *);
|
||||
static int SHA1Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
static void SHA1Final_int(u_int8_t *, void *);
|
||||
static int RMD160Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
static int SHA256Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
static int SHA384Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
static int SHA512Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
|
||||
static u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **);
|
||||
static u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **);
|
||||
|
||||
#define AESICM_BLOCKSIZE AES_BLOCK_LEN
|
||||
|
||||
struct aes_icm_ctx {
|
||||
u_int32_t ac_ek[4*(RIJNDAEL_MAXNR + 1)];
|
||||
/* ac_block is initalized to IV */
|
||||
u_int8_t ac_block[AESICM_BLOCKSIZE];
|
||||
int ac_nr;
|
||||
};
|
||||
|
||||
MALLOC_DEFINE(M_XDATA, "xform", "xform data buffers");
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_null = {
|
||||
CRYPTO_NULL_CBC, "NULL",
|
||||
/* NB: blocksize of 4 is to generate a properly aligned ESP header */
|
||||
NULL_BLOCK_LEN, 0, NULL_MIN_KEY, NULL_MAX_KEY,
|
||||
null_encrypt,
|
||||
null_decrypt,
|
||||
null_setkey,
|
||||
null_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_des = {
|
||||
CRYPTO_DES_CBC, "DES",
|
||||
DES_BLOCK_LEN, DES_BLOCK_LEN, DES_MIN_KEY, DES_MAX_KEY,
|
||||
des1_encrypt,
|
||||
des1_decrypt,
|
||||
des1_setkey,
|
||||
des1_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_3des = {
|
||||
CRYPTO_3DES_CBC, "3DES",
|
||||
DES3_BLOCK_LEN, DES3_BLOCK_LEN, TRIPLE_DES_MIN_KEY,
|
||||
TRIPLE_DES_MAX_KEY,
|
||||
des3_encrypt,
|
||||
des3_decrypt,
|
||||
des3_setkey,
|
||||
des3_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_blf = {
|
||||
CRYPTO_BLF_CBC, "Blowfish",
|
||||
BLOWFISH_BLOCK_LEN, BLOWFISH_BLOCK_LEN, BLOWFISH_MIN_KEY,
|
||||
BLOWFISH_MAX_KEY,
|
||||
blf_encrypt,
|
||||
blf_decrypt,
|
||||
blf_setkey,
|
||||
blf_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_cast5 = {
|
||||
CRYPTO_CAST_CBC, "CAST-128",
|
||||
CAST128_BLOCK_LEN, CAST128_BLOCK_LEN, CAST_MIN_KEY, CAST_MAX_KEY,
|
||||
cast5_encrypt,
|
||||
cast5_decrypt,
|
||||
cast5_setkey,
|
||||
cast5_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_skipjack = {
|
||||
CRYPTO_SKIPJACK_CBC, "Skipjack",
|
||||
SKIPJACK_BLOCK_LEN, SKIPJACK_BLOCK_LEN, SKIPJACK_MIN_KEY,
|
||||
SKIPJACK_MAX_KEY,
|
||||
skipjack_encrypt,
|
||||
skipjack_decrypt, skipjack_setkey,
|
||||
skipjack_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_rijndael128 = {
|
||||
CRYPTO_RIJNDAEL128_CBC, "Rijndael-128/AES",
|
||||
RIJNDAEL128_BLOCK_LEN, RIJNDAEL128_BLOCK_LEN, RIJNDAEL_MIN_KEY,
|
||||
RIJNDAEL_MAX_KEY,
|
||||
rijndael128_encrypt,
|
||||
rijndael128_decrypt,
|
||||
rijndael128_setkey,
|
||||
rijndael128_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_aes_icm = {
|
||||
CRYPTO_AES_ICM, "AES-ICM",
|
||||
AES_BLOCK_LEN, AES_BLOCK_LEN, AES_MIN_KEY, AES_MAX_KEY,
|
||||
aes_icm_crypt,
|
||||
aes_icm_crypt,
|
||||
aes_icm_setkey,
|
||||
rijndael128_zerokey,
|
||||
aes_icm_reinit,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_aes_nist_gcm = {
|
||||
CRYPTO_AES_NIST_GCM_16, "AES-GCM",
|
||||
AES_ICM_BLOCK_LEN, AES_GCM_IV_LEN, AES_MIN_KEY, AES_MAX_KEY,
|
||||
aes_icm_crypt,
|
||||
aes_icm_crypt,
|
||||
aes_icm_setkey,
|
||||
aes_icm_zerokey,
|
||||
aes_gcm_reinit,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_aes_nist_gmac = {
|
||||
CRYPTO_AES_NIST_GMAC, "AES-GMAC",
|
||||
AES_ICM_BLOCK_LEN, AES_GCM_IV_LEN, AES_MIN_KEY, AES_MAX_KEY,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_aes_xts = {
|
||||
CRYPTO_AES_XTS, "AES-XTS",
|
||||
AES_BLOCK_LEN, AES_XTS_IV_LEN, AES_XTS_MIN_KEY, AES_XTS_MAX_KEY,
|
||||
aes_xts_encrypt,
|
||||
aes_xts_decrypt,
|
||||
aes_xts_setkey,
|
||||
aes_xts_zerokey,
|
||||
aes_xts_reinit
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_arc4 = {
|
||||
CRYPTO_ARC4, "ARC4",
|
||||
ARC4_BLOCK_LEN, ARC4_IV_LEN, ARC4_MIN_KEY, ARC4_MAX_KEY,
|
||||
@ -275,711 +88,26 @@ struct enc_xform enc_xform_arc4 = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_camellia = {
|
||||
CRYPTO_CAMELLIA_CBC, "Camellia",
|
||||
CAMELLIA_BLOCK_LEN, CAMELLIA_BLOCK_LEN, CAMELLIA_MIN_KEY,
|
||||
CAMELLIA_MAX_KEY,
|
||||
cml_encrypt,
|
||||
cml_decrypt,
|
||||
cml_setkey,
|
||||
cml_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Authentication instances */
|
||||
struct auth_hash auth_hash_null = { /* NB: context isn't used */
|
||||
CRYPTO_NULL_HMAC, "NULL-HMAC",
|
||||
NULL_HMAC_KEY_LEN, NULL_HASH_LEN, sizeof(int), NULL_HMAC_BLOCK_LEN,
|
||||
null_init, null_reinit, null_reinit, null_update, null_final
|
||||
};
|
||||
/* Include the encryption algorithms */
|
||||
#include "xform_null.c"
|
||||
#include "xform_des1.c"
|
||||
#include "xform_des3.c"
|
||||
#include "xform_blf.c"
|
||||
#include "xform_cast5.c"
|
||||
#include "xform_skipjack.c"
|
||||
#include "xform_rijndael.c"
|
||||
#include "xform_aes_icm.c"
|
||||
#include "xform_aes_xts.c"
|
||||
#include "xform_cml.c"
|
||||
|
||||
/* Include the authentication and hashing algorithms */
|
||||
#include "xform_gmac.c"
|
||||
#include "xform_md5.c"
|
||||
#include "xform_rmd160.c"
|
||||
#include "xform_sha1.c"
|
||||
#include "xform_sha2.c"
|
||||
|
||||
/* Include the compression algorithms */
|
||||
#include "xform_deflate.c"
|
||||
|
||||
struct auth_hash auth_hash_hmac_md5 = {
|
||||
CRYPTO_MD5_HMAC, "HMAC-MD5",
|
||||
MD5_HMAC_KEY_LEN, MD5_HASH_LEN, sizeof(MD5_CTX), MD5_HMAC_BLOCK_LEN,
|
||||
(void (*) (void *)) MD5Init, NULL, NULL, MD5Update_int,
|
||||
(void (*) (u_int8_t *, void *)) MD5Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_hmac_sha1 = {
|
||||
CRYPTO_SHA1_HMAC, "HMAC-SHA1",
|
||||
SHA1_HMAC_KEY_LEN, SHA1_HASH_LEN, sizeof(SHA1_CTX), SHA1_HMAC_BLOCK_LEN,
|
||||
SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_hmac_ripemd_160 = {
|
||||
CRYPTO_RIPEMD160_HMAC, "HMAC-RIPEMD-160",
|
||||
RIPEMD160_HMAC_KEY_LEN, RIPEMD160_HASH_LEN, sizeof(RMD160_CTX),
|
||||
RIPEMD160_HMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) RMD160Init, NULL, NULL, RMD160Update_int,
|
||||
(void (*)(u_int8_t *, void *)) RMD160Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_key_md5 = {
|
||||
CRYPTO_MD5_KPDK, "Keyed MD5",
|
||||
NULL_HMAC_KEY_LEN, MD5_KPDK_HASH_LEN, sizeof(MD5_CTX), 0,
|
||||
(void (*)(void *)) MD5Init, NULL, NULL, MD5Update_int,
|
||||
(void (*)(u_int8_t *, void *)) MD5Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_key_sha1 = {
|
||||
CRYPTO_SHA1_KPDK, "Keyed SHA1",
|
||||
NULL_HMAC_KEY_LEN, SHA1_KPDK_HASH_LEN, sizeof(SHA1_CTX), 0,
|
||||
SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_hmac_sha2_256 = {
|
||||
CRYPTO_SHA2_256_HMAC, "HMAC-SHA2-256",
|
||||
SHA2_256_HMAC_KEY_LEN, SHA2_256_HASH_LEN, sizeof(SHA256_CTX),
|
||||
SHA2_256_HMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) SHA256_Init, NULL, NULL, SHA256Update_int,
|
||||
(void (*)(u_int8_t *, void *)) SHA256_Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_hmac_sha2_384 = {
|
||||
CRYPTO_SHA2_384_HMAC, "HMAC-SHA2-384",
|
||||
SHA2_384_HMAC_KEY_LEN, SHA2_384_HASH_LEN, sizeof(SHA384_CTX),
|
||||
SHA2_384_HMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) SHA384_Init, NULL, NULL, SHA384Update_int,
|
||||
(void (*)(u_int8_t *, void *)) SHA384_Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_hmac_sha2_512 = {
|
||||
CRYPTO_SHA2_512_HMAC, "HMAC-SHA2-512",
|
||||
SHA2_512_HMAC_KEY_LEN, SHA2_512_HASH_LEN, sizeof(SHA512_CTX),
|
||||
SHA2_512_HMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) SHA512_Init, NULL, NULL, SHA512Update_int,
|
||||
(void (*)(u_int8_t *, void *)) SHA512_Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_nist_gmac_aes_128 = {
|
||||
CRYPTO_AES_128_NIST_GMAC, "GMAC-AES-128",
|
||||
AES_128_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
|
||||
GMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) AES_GMAC_Init,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
|
||||
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
|
||||
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_nist_gmac_aes_192 = {
|
||||
CRYPTO_AES_192_NIST_GMAC, "GMAC-AES-192",
|
||||
AES_192_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
|
||||
GMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) AES_GMAC_Init,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
|
||||
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
|
||||
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_nist_gmac_aes_256 = {
|
||||
CRYPTO_AES_256_NIST_GMAC, "GMAC-AES-256",
|
||||
AES_256_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
|
||||
GMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) AES_GMAC_Init,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
|
||||
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
|
||||
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
|
||||
};
|
||||
|
||||
/* Compression instance */
|
||||
struct comp_algo comp_algo_deflate = {
|
||||
CRYPTO_DEFLATE_COMP, "Deflate",
|
||||
90, deflate_compress,
|
||||
deflate_decompress
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
null_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
}
|
||||
static void
|
||||
null_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
}
|
||||
static int
|
||||
null_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
*sched = NULL;
|
||||
return 0;
|
||||
}
|
||||
static void
|
||||
null_zerokey(u_int8_t **sched)
|
||||
{
|
||||
*sched = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
des1_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
des_cblock *cb = (des_cblock *) blk;
|
||||
des_key_schedule *p = (des_key_schedule *) key;
|
||||
|
||||
des_ecb_encrypt(cb, cb, p[0], DES_ENCRYPT);
|
||||
}
|
||||
|
||||
static void
|
||||
des1_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
des_cblock *cb = (des_cblock *) blk;
|
||||
des_key_schedule *p = (des_key_schedule *) key;
|
||||
|
||||
des_ecb_encrypt(cb, cb, p[0], DES_DECRYPT);
|
||||
}
|
||||
|
||||
static int
|
||||
des1_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
des_key_schedule *p;
|
||||
int err;
|
||||
|
||||
p = malloc(sizeof (des_key_schedule),
|
||||
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
|
||||
if (p != NULL) {
|
||||
des_set_key((des_cblock *) key, p[0]);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
*sched = (u_int8_t *) p;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
des1_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof (des_key_schedule));
|
||||
free(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
des3_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
des_cblock *cb = (des_cblock *) blk;
|
||||
des_key_schedule *p = (des_key_schedule *) key;
|
||||
|
||||
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_ENCRYPT);
|
||||
}
|
||||
|
||||
static void
|
||||
des3_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
des_cblock *cb = (des_cblock *) blk;
|
||||
des_key_schedule *p = (des_key_schedule *) key;
|
||||
|
||||
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_DECRYPT);
|
||||
}
|
||||
|
||||
static int
|
||||
des3_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
des_key_schedule *p;
|
||||
int err;
|
||||
|
||||
p = malloc(3*sizeof (des_key_schedule),
|
||||
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
|
||||
if (p != NULL) {
|
||||
des_set_key((des_cblock *)(key + 0), p[0]);
|
||||
des_set_key((des_cblock *)(key + 8), p[1]);
|
||||
des_set_key((des_cblock *)(key + 16), p[2]);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
*sched = (u_int8_t *) p;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
des3_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, 3*sizeof (des_key_schedule));
|
||||
free(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
blf_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
BF_LONG t[2];
|
||||
|
||||
memcpy(t, blk, sizeof (t));
|
||||
t[0] = ntohl(t[0]);
|
||||
t[1] = ntohl(t[1]);
|
||||
/* NB: BF_encrypt expects the block in host order! */
|
||||
BF_encrypt(t, (BF_KEY *) key);
|
||||
t[0] = htonl(t[0]);
|
||||
t[1] = htonl(t[1]);
|
||||
memcpy(blk, t, sizeof (t));
|
||||
}
|
||||
|
||||
static void
|
||||
blf_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
BF_LONG t[2];
|
||||
|
||||
memcpy(t, blk, sizeof (t));
|
||||
t[0] = ntohl(t[0]);
|
||||
t[1] = ntohl(t[1]);
|
||||
/* NB: BF_decrypt expects the block in host order! */
|
||||
BF_decrypt(t, (BF_KEY *) key);
|
||||
t[0] = htonl(t[0]);
|
||||
t[1] = htonl(t[1]);
|
||||
memcpy(blk, t, sizeof (t));
|
||||
}
|
||||
|
||||
static int
|
||||
blf_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
*sched = malloc(sizeof(BF_KEY),
|
||||
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
|
||||
if (*sched != NULL) {
|
||||
BF_set_key((BF_KEY *) *sched, len, key);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
blf_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof(BF_KEY));
|
||||
free(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
cast5_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
cast_encrypt((cast_key *) key, blk, blk);
|
||||
}
|
||||
|
||||
static void
|
||||
cast5_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
cast_decrypt((cast_key *) key, blk, blk);
|
||||
}
|
||||
|
||||
static int
|
||||
cast5_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
*sched = malloc(sizeof(cast_key), M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
|
||||
if (*sched != NULL) {
|
||||
cast_setkey((cast_key *)*sched, key, len);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
cast5_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof(cast_key));
|
||||
free(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
skipjack_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
skipjack_forwards(blk, blk, (u_int8_t **) key);
|
||||
}
|
||||
|
||||
static void
|
||||
skipjack_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
skipjack_backwards(blk, blk, (u_int8_t **) key);
|
||||
}
|
||||
|
||||
static int
|
||||
skipjack_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* NB: allocate all the memory that's needed at once */
|
||||
*sched = malloc(10 * (sizeof(u_int8_t *) + 0x100),
|
||||
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
|
||||
if (*sched != NULL) {
|
||||
u_int8_t** key_tables = (u_int8_t**) *sched;
|
||||
u_int8_t* table = (u_int8_t*) &key_tables[10];
|
||||
int k;
|
||||
|
||||
for (k = 0; k < 10; k++) {
|
||||
key_tables[k] = table;
|
||||
table += 0x100;
|
||||
}
|
||||
subkey_table_gen(key, (u_int8_t **) *sched);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
skipjack_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, 10 * (sizeof(u_int8_t *) + 0x100));
|
||||
free(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
rijndael128_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
rijndael_encrypt((rijndael_ctx *) key, (u_char *) blk, (u_char *) blk);
|
||||
}
|
||||
|
||||
static void
|
||||
rijndael128_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
rijndael_decrypt(((rijndael_ctx *) key), (u_char *) blk,
|
||||
(u_char *) blk);
|
||||
}
|
||||
|
||||
static int
|
||||
rijndael128_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (len != 16 && len != 24 && len != 32)
|
||||
return (EINVAL);
|
||||
*sched = malloc(sizeof(rijndael_ctx), M_CRYPTO_DATA,
|
||||
M_NOWAIT|M_ZERO);
|
||||
if (*sched != NULL) {
|
||||
rijndael_set_key((rijndael_ctx *) *sched, (u_char *) key,
|
||||
len * 8);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
rijndael128_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof(rijndael_ctx));
|
||||
free(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
aes_icm_reinit(caddr_t key, u_int8_t *iv)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
|
||||
ctx = (struct aes_icm_ctx *)key;
|
||||
bcopy(iv, ctx->ac_block, AESICM_BLOCKSIZE);
|
||||
}
|
||||
|
||||
void
|
||||
aes_gcm_reinit(caddr_t key, u_int8_t *iv)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
|
||||
aes_icm_reinit(key, iv);
|
||||
|
||||
ctx = (struct aes_icm_ctx *)key;
|
||||
/* GCM starts with 2 as counter 1 is used for final xor of tag. */
|
||||
bzero(&ctx->ac_block[AESICM_BLOCKSIZE - 4], 4);
|
||||
ctx->ac_block[AESICM_BLOCKSIZE - 1] = 2;
|
||||
}
|
||||
|
||||
void
|
||||
aes_icm_crypt(caddr_t key, u_int8_t *data)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
u_int8_t keystream[AESICM_BLOCKSIZE];
|
||||
int i;
|
||||
|
||||
ctx = (struct aes_icm_ctx *)key;
|
||||
rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream);
|
||||
for (i = 0; i < AESICM_BLOCKSIZE; i++)
|
||||
data[i] ^= keystream[i];
|
||||
explicit_bzero(keystream, sizeof(keystream));
|
||||
|
||||
/* increment counter */
|
||||
for (i = AESICM_BLOCKSIZE - 1;
|
||||
i >= 0; i--)
|
||||
if (++ctx->ac_block[i]) /* continue on overflow */
|
||||
break;
|
||||
}
|
||||
|
||||
int
|
||||
aes_icm_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
|
||||
if (len != 16 && len != 24 && len != 32)
|
||||
return EINVAL;
|
||||
|
||||
*sched = malloc(sizeof(struct aes_icm_ctx), M_CRYPTO_DATA,
|
||||
M_NOWAIT | M_ZERO);
|
||||
if (*sched == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
ctx = (struct aes_icm_ctx *)*sched;
|
||||
ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, (u_char *)key, len * 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
aes_icm_zerokey(u_int8_t **sched)
|
||||
{
|
||||
|
||||
bzero(*sched, sizeof(struct aes_icm_ctx));
|
||||
free(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
||||
|
||||
#define AES_XTS_BLOCKSIZE 16
|
||||
#define AES_XTS_IVSIZE 8
|
||||
#define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */
|
||||
|
||||
struct aes_xts_ctx {
|
||||
rijndael_ctx key1;
|
||||
rijndael_ctx key2;
|
||||
u_int8_t tweak[AES_XTS_BLOCKSIZE];
|
||||
};
|
||||
|
||||
void
|
||||
aes_xts_reinit(caddr_t key, u_int8_t *iv)
|
||||
{
|
||||
struct aes_xts_ctx *ctx = (struct aes_xts_ctx *)key;
|
||||
u_int64_t blocknum;
|
||||
u_int i;
|
||||
|
||||
/*
|
||||
* Prepare tweak as E_k2(IV). IV is specified as LE representation
|
||||
* of a 64-bit block number which we allow to be passed in directly.
|
||||
*/
|
||||
bcopy(iv, &blocknum, AES_XTS_IVSIZE);
|
||||
for (i = 0; i < AES_XTS_IVSIZE; i++) {
|
||||
ctx->tweak[i] = blocknum & 0xff;
|
||||
blocknum >>= 8;
|
||||
}
|
||||
/* Last 64 bits of IV are always zero */
|
||||
bzero(ctx->tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE);
|
||||
|
||||
rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak);
|
||||
}
|
||||
|
||||
static void
|
||||
aes_xts_crypt(struct aes_xts_ctx *ctx, u_int8_t *data, u_int do_encrypt)
|
||||
{
|
||||
u_int8_t block[AES_XTS_BLOCKSIZE];
|
||||
u_int i, carry_in, carry_out;
|
||||
|
||||
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
|
||||
block[i] = data[i] ^ ctx->tweak[i];
|
||||
|
||||
if (do_encrypt)
|
||||
rijndael_encrypt(&ctx->key1, block, data);
|
||||
else
|
||||
rijndael_decrypt(&ctx->key1, block, data);
|
||||
|
||||
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
|
||||
data[i] ^= ctx->tweak[i];
|
||||
|
||||
/* Exponentiate tweak */
|
||||
carry_in = 0;
|
||||
for (i = 0; i < AES_XTS_BLOCKSIZE; i++) {
|
||||
carry_out = ctx->tweak[i] & 0x80;
|
||||
ctx->tweak[i] = (ctx->tweak[i] << 1) | (carry_in ? 1 : 0);
|
||||
carry_in = carry_out;
|
||||
}
|
||||
if (carry_in)
|
||||
ctx->tweak[0] ^= AES_XTS_ALPHA;
|
||||
bzero(block, sizeof(block));
|
||||
}
|
||||
|
||||
void
|
||||
aes_xts_encrypt(caddr_t key, u_int8_t *data)
|
||||
{
|
||||
aes_xts_crypt((struct aes_xts_ctx *)key, data, 1);
|
||||
}
|
||||
|
||||
void
|
||||
aes_xts_decrypt(caddr_t key, u_int8_t *data)
|
||||
{
|
||||
aes_xts_crypt((struct aes_xts_ctx *)key, data, 0);
|
||||
}
|
||||
|
||||
int
|
||||
aes_xts_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
struct aes_xts_ctx *ctx;
|
||||
|
||||
if (len != 32 && len != 64)
|
||||
return EINVAL;
|
||||
|
||||
*sched = malloc(sizeof(struct aes_xts_ctx), M_CRYPTO_DATA,
|
||||
M_NOWAIT | M_ZERO);
|
||||
if (*sched == NULL)
|
||||
return ENOMEM;
|
||||
ctx = (struct aes_xts_ctx *)*sched;
|
||||
|
||||
rijndael_set_key(&ctx->key1, key, len * 4);
|
||||
rijndael_set_key(&ctx->key2, key + (len / 2), len * 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
aes_xts_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof(struct aes_xts_ctx));
|
||||
free(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
cml_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
camellia_encrypt((camellia_ctx *) key, (u_char *) blk, (u_char *) blk);
|
||||
}
|
||||
|
||||
static void
|
||||
cml_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
camellia_decrypt(((camellia_ctx *) key), (u_char *) blk,
|
||||
(u_char *) blk);
|
||||
}
|
||||
|
||||
static int
|
||||
cml_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (len != 16 && len != 24 && len != 32)
|
||||
return (EINVAL);
|
||||
*sched = malloc(sizeof(camellia_ctx), M_CRYPTO_DATA,
|
||||
M_NOWAIT|M_ZERO);
|
||||
if (*sched != NULL) {
|
||||
camellia_set_key((camellia_ctx *) *sched, (u_char *) key,
|
||||
len * 8);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
cml_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof(camellia_ctx));
|
||||
free(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* And now for auth.
|
||||
*/
|
||||
|
||||
static void
|
||||
null_init(void *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
null_reinit(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
null_update(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
null_final(u_int8_t *buf, void *ctx)
|
||||
{
|
||||
if (buf != (u_int8_t *) 0)
|
||||
bzero(buf, 12);
|
||||
}
|
||||
|
||||
static int
|
||||
RMD160Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
RMD160Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
MD5Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
MD5Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
SHA1Init_int(void *ctx)
|
||||
{
|
||||
SHA1Init(ctx);
|
||||
}
|
||||
|
||||
static int
|
||||
SHA1Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
SHA1Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
SHA1Final_int(u_int8_t *blk, void *ctx)
|
||||
{
|
||||
SHA1Final(blk, ctx);
|
||||
}
|
||||
|
||||
static int
|
||||
SHA256Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
SHA256_Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SHA384Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
SHA384_Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SHA512Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
SHA512_Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* And compression
|
||||
*/
|
||||
|
||||
static u_int32_t
|
||||
deflate_compress(data, size, out)
|
||||
u_int8_t *data;
|
||||
u_int32_t size;
|
||||
u_int8_t **out;
|
||||
{
|
||||
return deflate_global(data, size, 0, out);
|
||||
}
|
||||
|
||||
static u_int32_t
|
||||
deflate_decompress(data, size, out)
|
||||
u_int8_t *data;
|
||||
u_int32_t size;
|
||||
u_int8_t **out;
|
||||
{
|
||||
return deflate_global(data, size, 1, out);
|
||||
}
|
||||
|
@ -39,83 +39,9 @@
|
||||
#include <opencrypto/rmd160.h>
|
||||
#include <opencrypto/gmac.h>
|
||||
|
||||
/* Declarations */
|
||||
struct auth_hash {
|
||||
int type;
|
||||
char *name;
|
||||
u_int16_t keysize;
|
||||
u_int16_t hashsize;
|
||||
u_int16_t ctxsize;
|
||||
u_int16_t blocksize;
|
||||
void (*Init) (void *);
|
||||
void (*Setkey) (void *, const u_int8_t *, u_int16_t);
|
||||
void (*Reinit) (void *, const u_int8_t *, u_int16_t);
|
||||
int (*Update) (void *, const u_int8_t *, u_int16_t);
|
||||
void (*Final) (u_int8_t *, void *);
|
||||
};
|
||||
|
||||
/* XXX use a define common with other hash stuff ! */
|
||||
#define AH_ALEN_MAX 64 /* max authenticator hash length */
|
||||
|
||||
struct enc_xform {
|
||||
int type;
|
||||
char *name;
|
||||
u_int16_t blocksize;
|
||||
u_int16_t ivsize;
|
||||
u_int16_t minkey, maxkey;
|
||||
void (*encrypt) (caddr_t, u_int8_t *);
|
||||
void (*decrypt) (caddr_t, u_int8_t *);
|
||||
int (*setkey) (u_int8_t **, u_int8_t *, int len);
|
||||
void (*zerokey) (u_int8_t **);
|
||||
void (*reinit) (caddr_t, u_int8_t *);
|
||||
};
|
||||
|
||||
struct comp_algo {
|
||||
int type;
|
||||
char *name;
|
||||
size_t minlen;
|
||||
u_int32_t (*compress) (u_int8_t *, u_int32_t, u_int8_t **);
|
||||
u_int32_t (*decompress) (u_int8_t *, u_int32_t, u_int8_t **);
|
||||
};
|
||||
|
||||
union authctx {
|
||||
MD5_CTX md5ctx;
|
||||
SHA1_CTX sha1ctx;
|
||||
RMD160_CTX rmd160ctx;
|
||||
SHA256_CTX sha256ctx;
|
||||
SHA384_CTX sha384ctx;
|
||||
SHA512_CTX sha512ctx;
|
||||
struct aes_gmac_ctx aes_gmac_ctx;
|
||||
};
|
||||
|
||||
extern struct enc_xform enc_xform_null;
|
||||
extern struct enc_xform enc_xform_des;
|
||||
extern struct enc_xform enc_xform_3des;
|
||||
extern struct enc_xform enc_xform_blf;
|
||||
extern struct enc_xform enc_xform_cast5;
|
||||
extern struct enc_xform enc_xform_skipjack;
|
||||
extern struct enc_xform enc_xform_rijndael128;
|
||||
extern struct enc_xform enc_xform_aes_icm;
|
||||
extern struct enc_xform enc_xform_aes_nist_gcm;
|
||||
extern struct enc_xform enc_xform_aes_nist_gmac;
|
||||
extern struct enc_xform enc_xform_aes_xts;
|
||||
extern struct enc_xform enc_xform_arc4;
|
||||
extern struct enc_xform enc_xform_camellia;
|
||||
|
||||
extern struct auth_hash auth_hash_null;
|
||||
extern struct auth_hash auth_hash_key_md5;
|
||||
extern struct auth_hash auth_hash_key_sha1;
|
||||
extern struct auth_hash auth_hash_hmac_md5;
|
||||
extern struct auth_hash auth_hash_hmac_sha1;
|
||||
extern struct auth_hash auth_hash_hmac_ripemd_160;
|
||||
extern struct auth_hash auth_hash_hmac_sha2_256;
|
||||
extern struct auth_hash auth_hash_hmac_sha2_384;
|
||||
extern struct auth_hash auth_hash_hmac_sha2_512;
|
||||
extern struct auth_hash auth_hash_nist_gmac_aes_128;
|
||||
extern struct auth_hash auth_hash_nist_gmac_aes_192;
|
||||
extern struct auth_hash auth_hash_nist_gmac_aes_256;
|
||||
|
||||
extern struct comp_algo comp_algo_deflate;
|
||||
#include <opencrypto/xform_auth.h>
|
||||
#include <opencrypto/xform_comp.h>
|
||||
#include <opencrypto/xform_enc.h>
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/malloc.h>
|
||||
|
152
sys/opencrypto/xform_aes_icm.c
Normal file
152
sys/opencrypto/xform_aes_icm.c
Normal file
@ -0,0 +1,152 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <opencrypto/xform_enc.h>
|
||||
|
||||
static int aes_icm_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static void aes_icm_crypt(caddr_t, u_int8_t *);
|
||||
static void aes_icm_zerokey(u_int8_t **);
|
||||
static void aes_icm_reinit(caddr_t, u_int8_t *);
|
||||
static void aes_gcm_reinit(caddr_t, u_int8_t *);
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_aes_icm = {
|
||||
CRYPTO_AES_ICM, "AES-ICM",
|
||||
AES_BLOCK_LEN, AES_BLOCK_LEN, AES_MIN_KEY, AES_MAX_KEY,
|
||||
aes_icm_crypt,
|
||||
aes_icm_crypt,
|
||||
aes_icm_setkey,
|
||||
rijndael128_zerokey,
|
||||
aes_icm_reinit,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_aes_nist_gcm = {
|
||||
CRYPTO_AES_NIST_GCM_16, "AES-GCM",
|
||||
AES_ICM_BLOCK_LEN, AES_GCM_IV_LEN, AES_MIN_KEY, AES_MAX_KEY,
|
||||
aes_icm_crypt,
|
||||
aes_icm_crypt,
|
||||
aes_icm_setkey,
|
||||
aes_icm_zerokey,
|
||||
aes_gcm_reinit,
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
aes_icm_reinit(caddr_t key, u_int8_t *iv)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
|
||||
ctx = (struct aes_icm_ctx *)key;
|
||||
bcopy(iv, ctx->ac_block, AESICM_BLOCKSIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
aes_gcm_reinit(caddr_t key, u_int8_t *iv)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
|
||||
aes_icm_reinit(key, iv);
|
||||
|
||||
ctx = (struct aes_icm_ctx *)key;
|
||||
/* GCM starts with 2 as counter 1 is used for final xor of tag. */
|
||||
bzero(&ctx->ac_block[AESICM_BLOCKSIZE - 4], 4);
|
||||
ctx->ac_block[AESICM_BLOCKSIZE - 1] = 2;
|
||||
}
|
||||
|
||||
static void
|
||||
aes_icm_crypt(caddr_t key, u_int8_t *data)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
u_int8_t keystream[AESICM_BLOCKSIZE];
|
||||
int i;
|
||||
|
||||
ctx = (struct aes_icm_ctx *)key;
|
||||
rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream);
|
||||
for (i = 0; i < AESICM_BLOCKSIZE; i++)
|
||||
data[i] ^= keystream[i];
|
||||
explicit_bzero(keystream, sizeof(keystream));
|
||||
|
||||
/* increment counter */
|
||||
for (i = AESICM_BLOCKSIZE - 1;
|
||||
i >= 0; i--)
|
||||
if (++ctx->ac_block[i]) /* continue on overflow */
|
||||
break;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_icm_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
|
||||
if (len != 16 && len != 24 && len != 32)
|
||||
return EINVAL;
|
||||
|
||||
*sched = KMALLOC(sizeof(struct aes_icm_ctx), M_CRYPTO_DATA,
|
||||
M_NOWAIT | M_ZERO);
|
||||
if (*sched == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
ctx = (struct aes_icm_ctx *)*sched;
|
||||
ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, (u_char *)key, len * 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
aes_icm_zerokey(u_int8_t **sched)
|
||||
{
|
||||
|
||||
bzero(*sched, sizeof(struct aes_icm_ctx));
|
||||
KFREE(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
164
sys/opencrypto/xform_aes_xts.c
Normal file
164
sys/opencrypto/xform_aes_xts.c
Normal file
@ -0,0 +1,164 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <opencrypto/xform_enc.h>
|
||||
|
||||
static int aes_xts_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static void aes_xts_encrypt(caddr_t, u_int8_t *);
|
||||
static void aes_xts_decrypt(caddr_t, u_int8_t *);
|
||||
static void aes_xts_zerokey(u_int8_t **);
|
||||
static void aes_xts_reinit(caddr_t, u_int8_t *);
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_aes_xts = {
|
||||
CRYPTO_AES_XTS, "AES-XTS",
|
||||
AES_BLOCK_LEN, AES_XTS_IV_LEN, AES_XTS_MIN_KEY, AES_XTS_MAX_KEY,
|
||||
aes_xts_encrypt,
|
||||
aes_xts_decrypt,
|
||||
aes_xts_setkey,
|
||||
aes_xts_zerokey,
|
||||
aes_xts_reinit
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
aes_xts_reinit(caddr_t key, u_int8_t *iv)
|
||||
{
|
||||
struct aes_xts_ctx *ctx = (struct aes_xts_ctx *)key;
|
||||
u_int64_t blocknum;
|
||||
u_int i;
|
||||
|
||||
/*
|
||||
* Prepare tweak as E_k2(IV). IV is specified as LE representation
|
||||
* of a 64-bit block number which we allow to be passed in directly.
|
||||
*/
|
||||
bcopy(iv, &blocknum, AES_XTS_IVSIZE);
|
||||
for (i = 0; i < AES_XTS_IVSIZE; i++) {
|
||||
ctx->tweak[i] = blocknum & 0xff;
|
||||
blocknum >>= 8;
|
||||
}
|
||||
/* Last 64 bits of IV are always zero */
|
||||
bzero(ctx->tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE);
|
||||
|
||||
rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak);
|
||||
}
|
||||
|
||||
static void
|
||||
aes_xts_crypt(struct aes_xts_ctx *ctx, u_int8_t *data, u_int do_encrypt)
|
||||
{
|
||||
u_int8_t block[AES_XTS_BLOCKSIZE];
|
||||
u_int i, carry_in, carry_out;
|
||||
|
||||
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
|
||||
block[i] = data[i] ^ ctx->tweak[i];
|
||||
|
||||
if (do_encrypt)
|
||||
rijndael_encrypt(&ctx->key1, block, data);
|
||||
else
|
||||
rijndael_decrypt(&ctx->key1, block, data);
|
||||
|
||||
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
|
||||
data[i] ^= ctx->tweak[i];
|
||||
|
||||
/* Exponentiate tweak */
|
||||
carry_in = 0;
|
||||
for (i = 0; i < AES_XTS_BLOCKSIZE; i++) {
|
||||
carry_out = ctx->tweak[i] & 0x80;
|
||||
ctx->tweak[i] = (ctx->tweak[i] << 1) | (carry_in ? 1 : 0);
|
||||
carry_in = carry_out;
|
||||
}
|
||||
if (carry_in)
|
||||
ctx->tweak[0] ^= AES_XTS_ALPHA;
|
||||
bzero(block, sizeof(block));
|
||||
}
|
||||
|
||||
static void
|
||||
aes_xts_encrypt(caddr_t key, u_int8_t *data)
|
||||
{
|
||||
aes_xts_crypt((struct aes_xts_ctx *)key, data, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
aes_xts_decrypt(caddr_t key, u_int8_t *data)
|
||||
{
|
||||
aes_xts_crypt((struct aes_xts_ctx *)key, data, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
aes_xts_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
struct aes_xts_ctx *ctx;
|
||||
|
||||
if (len != 32 && len != 64)
|
||||
return EINVAL;
|
||||
|
||||
*sched = KMALLOC(sizeof(struct aes_xts_ctx), M_CRYPTO_DATA,
|
||||
M_NOWAIT | M_ZERO);
|
||||
if (*sched == NULL)
|
||||
return ENOMEM;
|
||||
ctx = (struct aes_xts_ctx *)*sched;
|
||||
|
||||
rijndael_set_key(&ctx->key1, key, len * 4);
|
||||
rijndael_set_key(&ctx->key2, key + (len / 2), len * 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
aes_xts_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof(struct aes_xts_ctx));
|
||||
KFREE(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
89
sys/opencrypto/xform_auth.h
Normal file
89
sys/opencrypto/xform_auth.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: xform.h,v 1.8 2001/08/28 12:20:43 ben Exp $ */
|
||||
|
||||
/*-
|
||||
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
|
||||
*
|
||||
* This code was written by Angelos D. Keromytis in Athens, Greece, in
|
||||
* February 2000. Network Security Technologies Inc. (NSTI) kindly
|
||||
* supported the development of this code.
|
||||
*
|
||||
* Copyright (c) 2000 Angelos D. Keromytis
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all source code copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_XFORM_AUTH_H_
|
||||
#define _CRYPTO_XFORM_AUTH_H_
|
||||
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <sys/md5.h>
|
||||
#include <crypto/sha1.h>
|
||||
#include <crypto/sha2/sha256.h>
|
||||
#include <crypto/sha2/sha384.h>
|
||||
#include <crypto/sha2/sha512.h>
|
||||
#include <opencrypto/rmd160.h>
|
||||
#include <opencrypto/gmac.h>
|
||||
|
||||
#include <opencrypto/cryptodev.h>
|
||||
#include <opencrypto/xform_userland.h>
|
||||
|
||||
/* XXX use a define common with other hash stuff ! */
|
||||
#define AH_ALEN_MAX 64 /* max authenticator hash length */
|
||||
|
||||
/* Declarations */
|
||||
struct auth_hash {
|
||||
int type;
|
||||
char *name;
|
||||
u_int16_t keysize;
|
||||
u_int16_t hashsize;
|
||||
u_int16_t ctxsize;
|
||||
u_int16_t blocksize;
|
||||
void (*Init) (void *);
|
||||
void (*Setkey) (void *, const u_int8_t *, u_int16_t);
|
||||
void (*Reinit) (void *, const u_int8_t *, u_int16_t);
|
||||
int (*Update) (void *, const u_int8_t *, u_int16_t);
|
||||
void (*Final) (u_int8_t *, void *);
|
||||
};
|
||||
|
||||
extern struct auth_hash auth_hash_null;
|
||||
extern struct auth_hash auth_hash_key_md5;
|
||||
extern struct auth_hash auth_hash_key_sha1;
|
||||
extern struct auth_hash auth_hash_hmac_md5;
|
||||
extern struct auth_hash auth_hash_hmac_sha1;
|
||||
extern struct auth_hash auth_hash_hmac_ripemd_160;
|
||||
extern struct auth_hash auth_hash_hmac_sha2_256;
|
||||
extern struct auth_hash auth_hash_hmac_sha2_384;
|
||||
extern struct auth_hash auth_hash_hmac_sha2_512;
|
||||
extern struct auth_hash auth_hash_nist_gmac_aes_128;
|
||||
extern struct auth_hash auth_hash_nist_gmac_aes_192;
|
||||
extern struct auth_hash auth_hash_nist_gmac_aes_256;
|
||||
|
||||
union authctx {
|
||||
MD5_CTX md5ctx;
|
||||
SHA1_CTX sha1ctx;
|
||||
RMD160_CTX rmd160ctx;
|
||||
SHA256_CTX sha256ctx;
|
||||
SHA384_CTX sha384ctx;
|
||||
SHA512_CTX sha512ctx;
|
||||
struct aes_gmac_ctx aes_gmac_ctx;
|
||||
};
|
||||
|
||||
#endif /* _CRYPTO_XFORM_AUTH_H_ */
|
127
sys/opencrypto/xform_blf.c
Normal file
127
sys/opencrypto/xform_blf.c
Normal file
@ -0,0 +1,127 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <crypto/blowfish/blowfish.h>
|
||||
#include <opencrypto/xform_enc.h>
|
||||
|
||||
static int blf_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static void blf_encrypt(caddr_t, u_int8_t *);
|
||||
static void blf_decrypt(caddr_t, u_int8_t *);
|
||||
static void blf_zerokey(u_int8_t **);
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_blf = {
|
||||
CRYPTO_BLF_CBC, "Blowfish",
|
||||
BLOWFISH_BLOCK_LEN, BLOWFISH_BLOCK_LEN, BLOWFISH_MIN_KEY,
|
||||
BLOWFISH_MAX_KEY,
|
||||
blf_encrypt,
|
||||
blf_decrypt,
|
||||
blf_setkey,
|
||||
blf_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
blf_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
BF_LONG t[2];
|
||||
|
||||
memcpy(t, blk, sizeof (t));
|
||||
t[0] = ntohl(t[0]);
|
||||
t[1] = ntohl(t[1]);
|
||||
/* NB: BF_encrypt expects the block in host order! */
|
||||
BF_encrypt(t, (BF_KEY *) key);
|
||||
t[0] = htonl(t[0]);
|
||||
t[1] = htonl(t[1]);
|
||||
memcpy(blk, t, sizeof (t));
|
||||
}
|
||||
|
||||
static void
|
||||
blf_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
BF_LONG t[2];
|
||||
|
||||
memcpy(t, blk, sizeof (t));
|
||||
t[0] = ntohl(t[0]);
|
||||
t[1] = ntohl(t[1]);
|
||||
/* NB: BF_decrypt expects the block in host order! */
|
||||
BF_decrypt(t, (BF_KEY *) key);
|
||||
t[0] = htonl(t[0]);
|
||||
t[1] = htonl(t[1]);
|
||||
memcpy(blk, t, sizeof (t));
|
||||
}
|
||||
|
||||
static int
|
||||
blf_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
*sched = KMALLOC(sizeof(BF_KEY),
|
||||
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
|
||||
if (*sched != NULL) {
|
||||
BF_set_key((BF_KEY *) *sched, len, key);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
blf_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof(BF_KEY));
|
||||
KFREE(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
107
sys/opencrypto/xform_cast5.c
Normal file
107
sys/opencrypto/xform_cast5.c
Normal file
@ -0,0 +1,107 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <opencrypto/cast.h>
|
||||
#include <opencrypto/xform_enc.h>
|
||||
|
||||
static int cast5_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static void cast5_encrypt(caddr_t, u_int8_t *);
|
||||
static void cast5_decrypt(caddr_t, u_int8_t *);
|
||||
static void cast5_zerokey(u_int8_t **);
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_cast5 = {
|
||||
CRYPTO_CAST_CBC, "CAST-128",
|
||||
CAST128_BLOCK_LEN, CAST128_BLOCK_LEN, CAST_MIN_KEY, CAST_MAX_KEY,
|
||||
cast5_encrypt,
|
||||
cast5_decrypt,
|
||||
cast5_setkey,
|
||||
cast5_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
cast5_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
cast_encrypt((cast_key *) key, blk, blk);
|
||||
}
|
||||
|
||||
static void
|
||||
cast5_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
cast_decrypt((cast_key *) key, blk, blk);
|
||||
}
|
||||
|
||||
static int
|
||||
cast5_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
*sched = KMALLOC(sizeof(cast_key), M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
|
||||
if (*sched != NULL) {
|
||||
cast_setkey((cast_key *)*sched, key, len);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
cast5_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof(cast_key));
|
||||
KFREE(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
113
sys/opencrypto/xform_cml.c
Normal file
113
sys/opencrypto/xform_cml.c
Normal file
@ -0,0 +1,113 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <crypto/camellia/camellia.h>
|
||||
#include <opencrypto/xform_enc.h>
|
||||
|
||||
static int cml_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static void cml_encrypt(caddr_t, u_int8_t *);
|
||||
static void cml_decrypt(caddr_t, u_int8_t *);
|
||||
static void cml_zerokey(u_int8_t **);
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_camellia = {
|
||||
CRYPTO_CAMELLIA_CBC, "Camellia",
|
||||
CAMELLIA_BLOCK_LEN, CAMELLIA_BLOCK_LEN, CAMELLIA_MIN_KEY,
|
||||
CAMELLIA_MAX_KEY,
|
||||
cml_encrypt,
|
||||
cml_decrypt,
|
||||
cml_setkey,
|
||||
cml_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
cml_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
camellia_encrypt((camellia_ctx *) key, (u_char *) blk, (u_char *) blk);
|
||||
}
|
||||
|
||||
static void
|
||||
cml_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
camellia_decrypt(((camellia_ctx *) key), (u_char *) blk,
|
||||
(u_char *) blk);
|
||||
}
|
||||
|
||||
static int
|
||||
cml_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (len != 16 && len != 24 && len != 32)
|
||||
return (EINVAL);
|
||||
*sched = KMALLOC(sizeof(camellia_ctx), M_CRYPTO_DATA,
|
||||
M_NOWAIT|M_ZERO);
|
||||
if (*sched != NULL) {
|
||||
camellia_set_key((camellia_ctx *) *sched, (u_char *) key,
|
||||
len * 8);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
cml_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof(camellia_ctx));
|
||||
KFREE(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
52
sys/opencrypto/xform_comp.h
Normal file
52
sys/opencrypto/xform_comp.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: xform.h,v 1.8 2001/08/28 12:20:43 ben Exp $ */
|
||||
|
||||
/*-
|
||||
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
|
||||
*
|
||||
* This code was written by Angelos D. Keromytis in Athens, Greece, in
|
||||
* February 2000. Network Security Technologies Inc. (NSTI) kindly
|
||||
* supported the development of this code.
|
||||
*
|
||||
* Copyright (c) 2000 Angelos D. Keromytis
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all source code copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_XFORM_COMP_H_
|
||||
#define _CRYPTO_XFORM_COMP_H_
|
||||
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <opencrypto/deflate.h>
|
||||
#include <opencrypto/cryptodev.h>
|
||||
#include <opencrypto/xform_userland.h>
|
||||
|
||||
/* Declarations */
|
||||
struct comp_algo {
|
||||
int type;
|
||||
char *name;
|
||||
size_t minlen;
|
||||
u_int32_t (*compress) (u_int8_t *, u_int32_t, u_int8_t **);
|
||||
u_int32_t (*decompress) (u_int8_t *, u_int32_t, u_int8_t **);
|
||||
};
|
||||
|
||||
extern struct comp_algo comp_algo_deflate;
|
||||
|
||||
#endif /* _CRYPTO_XFORM_COMP_H_ */
|
86
sys/opencrypto/xform_deflate.c
Normal file
86
sys/opencrypto/xform_deflate.c
Normal file
@ -0,0 +1,86 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <opencrypto/deflate.h>
|
||||
#include <opencrypto/xform_comp.h>
|
||||
|
||||
static u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **);
|
||||
static u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **);
|
||||
|
||||
/* Compression instance */
|
||||
struct comp_algo comp_algo_deflate = {
|
||||
CRYPTO_DEFLATE_COMP, "Deflate",
|
||||
90, deflate_compress,
|
||||
deflate_decompress
|
||||
};
|
||||
|
||||
/*
|
||||
* And compression
|
||||
*/
|
||||
|
||||
static u_int32_t
|
||||
deflate_compress(data, size, out)
|
||||
u_int8_t *data;
|
||||
u_int32_t size;
|
||||
u_int8_t **out;
|
||||
{
|
||||
return deflate_global(data, size, 0, out);
|
||||
}
|
||||
|
||||
static u_int32_t
|
||||
deflate_decompress(data, size, out)
|
||||
u_int8_t *data;
|
||||
u_int32_t size;
|
||||
u_int8_t **out;
|
||||
{
|
||||
return deflate_global(data, size, 1, out);
|
||||
}
|
116
sys/opencrypto/xform_des1.c
Normal file
116
sys/opencrypto/xform_des1.c
Normal file
@ -0,0 +1,116 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <crypto/des/des.h>
|
||||
#include <opencrypto/xform_enc.h>
|
||||
|
||||
static int des1_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static void des1_encrypt(caddr_t, u_int8_t *);
|
||||
static void des1_decrypt(caddr_t, u_int8_t *);
|
||||
static void des1_zerokey(u_int8_t **);
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_des = {
|
||||
CRYPTO_DES_CBC, "DES",
|
||||
DES_BLOCK_LEN, DES_BLOCK_LEN, DES_MIN_KEY, DES_MAX_KEY,
|
||||
des1_encrypt,
|
||||
des1_decrypt,
|
||||
des1_setkey,
|
||||
des1_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
des1_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
des_cblock *cb = (des_cblock *) blk;
|
||||
des_key_schedule *p = (des_key_schedule *) key;
|
||||
|
||||
des_ecb_encrypt(cb, cb, p[0], DES_ENCRYPT);
|
||||
}
|
||||
|
||||
static void
|
||||
des1_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
des_cblock *cb = (des_cblock *) blk;
|
||||
des_key_schedule *p = (des_key_schedule *) key;
|
||||
|
||||
des_ecb_encrypt(cb, cb, p[0], DES_DECRYPT);
|
||||
}
|
||||
|
||||
static int
|
||||
des1_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
des_key_schedule *p;
|
||||
int err;
|
||||
|
||||
p = KMALLOC(sizeof (des_key_schedule),
|
||||
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
|
||||
if (p != NULL) {
|
||||
des_set_key((des_cblock *) key, p[0]);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
*sched = (u_int8_t *) p;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
des1_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof (des_key_schedule));
|
||||
KFREE(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
119
sys/opencrypto/xform_des3.c
Normal file
119
sys/opencrypto/xform_des3.c
Normal file
@ -0,0 +1,119 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <crypto/des/des.h>
|
||||
#include <opencrypto/xform_enc.h>
|
||||
|
||||
static int des3_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static void des3_encrypt(caddr_t, u_int8_t *);
|
||||
static void des3_decrypt(caddr_t, u_int8_t *);
|
||||
static void des3_zerokey(u_int8_t **);
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_3des = {
|
||||
CRYPTO_3DES_CBC, "3DES",
|
||||
DES3_BLOCK_LEN, DES3_BLOCK_LEN, TRIPLE_DES_MIN_KEY,
|
||||
TRIPLE_DES_MAX_KEY,
|
||||
des3_encrypt,
|
||||
des3_decrypt,
|
||||
des3_setkey,
|
||||
des3_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
des3_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
des_cblock *cb = (des_cblock *) blk;
|
||||
des_key_schedule *p = (des_key_schedule *) key;
|
||||
|
||||
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_ENCRYPT);
|
||||
}
|
||||
|
||||
static void
|
||||
des3_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
des_cblock *cb = (des_cblock *) blk;
|
||||
des_key_schedule *p = (des_key_schedule *) key;
|
||||
|
||||
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_DECRYPT);
|
||||
}
|
||||
|
||||
static int
|
||||
des3_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
des_key_schedule *p;
|
||||
int err;
|
||||
|
||||
p = KMALLOC(3*sizeof (des_key_schedule),
|
||||
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
|
||||
if (p != NULL) {
|
||||
des_set_key((des_cblock *)(key + 0), p[0]);
|
||||
des_set_key((des_cblock *)(key + 8), p[1]);
|
||||
des_set_key((des_cblock *)(key + 16), p[2]);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
*sched = (u_int8_t *) p;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
des3_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, 3*sizeof (des_key_schedule));
|
||||
KFREE(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
92
sys/opencrypto/xform_enc.h
Normal file
92
sys/opencrypto/xform_enc.h
Normal file
@ -0,0 +1,92 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: xform.h,v 1.8 2001/08/28 12:20:43 ben Exp $ */
|
||||
|
||||
/*-
|
||||
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
|
||||
*
|
||||
* This code was written by Angelos D. Keromytis in Athens, Greece, in
|
||||
* February 2000. Network Security Technologies Inc. (NSTI) kindly
|
||||
* supported the development of this code.
|
||||
*
|
||||
* Copyright (c) 2000 Angelos D. Keromytis
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all source code copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_XFORM_ENC_H_
|
||||
#define _CRYPTO_XFORM_ENC_H_
|
||||
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/errno.h>
|
||||
#include <crypto/blowfish/blowfish.h>
|
||||
#include <crypto/des/des.h>
|
||||
#include <crypto/rijndael/rijndael.h>
|
||||
#include <crypto/camellia/camellia.h>
|
||||
#include <opencrypto/cast.h>
|
||||
#include <opencrypto/skipjack.h>
|
||||
#include <opencrypto/cryptodev.h>
|
||||
#include <opencrypto/xform_userland.h>
|
||||
|
||||
#define AESICM_BLOCKSIZE AES_BLOCK_LEN
|
||||
#define AES_XTS_BLOCKSIZE 16
|
||||
#define AES_XTS_IVSIZE 8
|
||||
#define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */
|
||||
|
||||
/* Declarations */
|
||||
struct enc_xform {
|
||||
int type;
|
||||
char *name;
|
||||
u_int16_t blocksize;
|
||||
u_int16_t ivsize;
|
||||
u_int16_t minkey, maxkey;
|
||||
void (*encrypt) (caddr_t, u_int8_t *);
|
||||
void (*decrypt) (caddr_t, u_int8_t *);
|
||||
int (*setkey) (u_int8_t **, u_int8_t *, int len);
|
||||
void (*zerokey) (u_int8_t **);
|
||||
void (*reinit) (caddr_t, u_int8_t *);
|
||||
};
|
||||
|
||||
|
||||
extern struct enc_xform enc_xform_null;
|
||||
extern struct enc_xform enc_xform_des;
|
||||
extern struct enc_xform enc_xform_3des;
|
||||
extern struct enc_xform enc_xform_blf;
|
||||
extern struct enc_xform enc_xform_cast5;
|
||||
extern struct enc_xform enc_xform_skipjack;
|
||||
extern struct enc_xform enc_xform_rijndael128;
|
||||
extern struct enc_xform enc_xform_aes_icm;
|
||||
extern struct enc_xform enc_xform_aes_nist_gcm;
|
||||
extern struct enc_xform enc_xform_aes_nist_gmac;
|
||||
extern struct enc_xform enc_xform_aes_xts;
|
||||
extern struct enc_xform enc_xform_arc4;
|
||||
extern struct enc_xform enc_xform_camellia;
|
||||
|
||||
struct aes_icm_ctx {
|
||||
u_int32_t ac_ek[4*(RIJNDAEL_MAXNR + 1)];
|
||||
/* ac_block is initalized to IV */
|
||||
u_int8_t ac_block[AESICM_BLOCKSIZE];
|
||||
int ac_nr;
|
||||
};
|
||||
|
||||
struct aes_xts_ctx {
|
||||
rijndael_ctx key1;
|
||||
rijndael_ctx key2;
|
||||
u_int8_t tweak[AES_XTS_BLOCKSIZE];
|
||||
};
|
||||
|
||||
#endif /* _CRYPTO_XFORM_ENC_H_ */
|
99
sys/opencrypto/xform_gmac.c
Normal file
99
sys/opencrypto/xform_gmac.c
Normal file
@ -0,0 +1,99 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <opencrypto/gmac.h>
|
||||
#include <opencrypto/xform_auth.h>
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_aes_nist_gmac = {
|
||||
CRYPTO_AES_NIST_GMAC, "AES-GMAC",
|
||||
AES_ICM_BLOCK_LEN, AES_GCM_IV_LEN, AES_MIN_KEY, AES_MAX_KEY,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Authentication instances */
|
||||
struct auth_hash auth_hash_nist_gmac_aes_128 = {
|
||||
CRYPTO_AES_128_NIST_GMAC, "GMAC-AES-128",
|
||||
AES_128_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
|
||||
GMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) AES_GMAC_Init,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
|
||||
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
|
||||
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_nist_gmac_aes_192 = {
|
||||
CRYPTO_AES_192_NIST_GMAC, "GMAC-AES-192",
|
||||
AES_192_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
|
||||
GMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) AES_GMAC_Init,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
|
||||
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
|
||||
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_nist_gmac_aes_256 = {
|
||||
CRYPTO_AES_256_NIST_GMAC, "GMAC-AES-256",
|
||||
AES_256_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
|
||||
GMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) AES_GMAC_Init,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
|
||||
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
|
||||
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
|
||||
};
|
81
sys/opencrypto/xform_md5.c
Normal file
81
sys/opencrypto/xform_md5.c
Normal file
@ -0,0 +1,81 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/md5.h>
|
||||
#include <opencrypto/xform_auth.h>
|
||||
|
||||
static int MD5Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
|
||||
/* Authentication instances */
|
||||
struct auth_hash auth_hash_hmac_md5 = {
|
||||
CRYPTO_MD5_HMAC, "HMAC-MD5",
|
||||
MD5_HMAC_KEY_LEN, MD5_HASH_LEN, sizeof(MD5_CTX), MD5_HMAC_BLOCK_LEN,
|
||||
(void (*) (void *)) MD5Init, NULL, NULL, MD5Update_int,
|
||||
(void (*) (u_int8_t *, void *)) MD5Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_key_md5 = {
|
||||
CRYPTO_MD5_KPDK, "Keyed MD5",
|
||||
NULL_HMAC_KEY_LEN, MD5_KPDK_HASH_LEN, sizeof(MD5_CTX), 0,
|
||||
(void (*)(void *)) MD5Init, NULL, NULL, MD5Update_int,
|
||||
(void (*)(u_int8_t *, void *)) MD5Final
|
||||
};
|
||||
|
||||
/*
|
||||
* And now for auth.
|
||||
*/
|
||||
static int
|
||||
MD5Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
MD5Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
136
sys/opencrypto/xform_null.c
Normal file
136
sys/opencrypto/xform_null.c
Normal file
@ -0,0 +1,136 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <opencrypto/xform_auth.h>
|
||||
#include <opencrypto/xform_enc.h>
|
||||
|
||||
static int null_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static void null_encrypt(caddr_t, u_int8_t *);
|
||||
static void null_decrypt(caddr_t, u_int8_t *);
|
||||
static void null_zerokey(u_int8_t **);
|
||||
|
||||
static void null_init(void *);
|
||||
static void null_reinit(void *ctx, const u_int8_t *buf, u_int16_t len);
|
||||
static int null_update(void *, const u_int8_t *, u_int16_t);
|
||||
static void null_final(u_int8_t *, void *);
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_null = {
|
||||
CRYPTO_NULL_CBC, "NULL",
|
||||
/* NB: blocksize of 4 is to generate a properly aligned ESP header */
|
||||
NULL_BLOCK_LEN, 0, NULL_MIN_KEY, NULL_MAX_KEY,
|
||||
null_encrypt,
|
||||
null_decrypt,
|
||||
null_setkey,
|
||||
null_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Authentication instances */
|
||||
struct auth_hash auth_hash_null = { /* NB: context isn't used */
|
||||
CRYPTO_NULL_HMAC, "NULL-HMAC",
|
||||
NULL_HMAC_KEY_LEN, NULL_HASH_LEN, sizeof(int), NULL_HMAC_BLOCK_LEN,
|
||||
null_init, null_reinit, null_reinit, null_update, null_final
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
null_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
null_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
null_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
*sched = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
null_zerokey(u_int8_t **sched)
|
||||
{
|
||||
*sched = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* And now for auth.
|
||||
*/
|
||||
|
||||
static void
|
||||
null_init(void *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
null_reinit(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
null_update(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
null_final(u_int8_t *buf, void *ctx)
|
||||
{
|
||||
if (buf != (u_int8_t *) 0)
|
||||
bzero(buf, 12);
|
||||
}
|
113
sys/opencrypto/xform_rijndael.c
Normal file
113
sys/opencrypto/xform_rijndael.c
Normal file
@ -0,0 +1,113 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <crypto/rijndael/rijndael.h>
|
||||
#include <opencrypto/xform_enc.h>
|
||||
|
||||
static int rijndael128_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static void rijndael128_encrypt(caddr_t, u_int8_t *);
|
||||
static void rijndael128_decrypt(caddr_t, u_int8_t *);
|
||||
static void rijndael128_zerokey(u_int8_t **);
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_rijndael128 = {
|
||||
CRYPTO_RIJNDAEL128_CBC, "Rijndael-128/AES",
|
||||
RIJNDAEL128_BLOCK_LEN, RIJNDAEL128_BLOCK_LEN, RIJNDAEL_MIN_KEY,
|
||||
RIJNDAEL_MAX_KEY,
|
||||
rijndael128_encrypt,
|
||||
rijndael128_decrypt,
|
||||
rijndael128_setkey,
|
||||
rijndael128_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
rijndael128_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
rijndael_encrypt((rijndael_ctx *) key, (u_char *) blk, (u_char *) blk);
|
||||
}
|
||||
|
||||
static void
|
||||
rijndael128_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
rijndael_decrypt(((rijndael_ctx *) key), (u_char *) blk,
|
||||
(u_char *) blk);
|
||||
}
|
||||
|
||||
static int
|
||||
rijndael128_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (len != 16 && len != 24 && len != 32)
|
||||
return (EINVAL);
|
||||
*sched = KMALLOC(sizeof(rijndael_ctx), M_CRYPTO_DATA,
|
||||
M_NOWAIT|M_ZERO);
|
||||
if (*sched != NULL) {
|
||||
rijndael_set_key((rijndael_ctx *) *sched, (u_char *) key,
|
||||
len * 8);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
rijndael128_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, sizeof(rijndael_ctx));
|
||||
KFREE(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
75
sys/opencrypto/xform_rmd160.c
Normal file
75
sys/opencrypto/xform_rmd160.c
Normal file
@ -0,0 +1,75 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <opencrypto/rmd160.h>
|
||||
#include <opencrypto/xform_auth.h>
|
||||
|
||||
static int RMD160Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
|
||||
/* Authentication instances */
|
||||
struct auth_hash auth_hash_hmac_ripemd_160 = {
|
||||
CRYPTO_RIPEMD160_HMAC, "HMAC-RIPEMD-160",
|
||||
RIPEMD160_HMAC_KEY_LEN, RIPEMD160_HASH_LEN, sizeof(RMD160_CTX),
|
||||
RIPEMD160_HMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) RMD160Init, NULL, NULL, RMD160Update_int,
|
||||
(void (*)(u_int8_t *, void *)) RMD160Final
|
||||
};
|
||||
|
||||
/*
|
||||
* And now for auth.
|
||||
*/
|
||||
static int
|
||||
RMD160Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
RMD160Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
93
sys/opencrypto/xform_sha1.c
Normal file
93
sys/opencrypto/xform_sha1.c
Normal file
@ -0,0 +1,93 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <crypto/sha1.h>
|
||||
#include <opencrypto/xform_auth.h>
|
||||
|
||||
static void SHA1Init_int(void *);
|
||||
static int SHA1Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
static void SHA1Final_int(u_int8_t *, void *);
|
||||
|
||||
/* Authentication instances */
|
||||
struct auth_hash auth_hash_hmac_sha1 = {
|
||||
CRYPTO_SHA1_HMAC, "HMAC-SHA1",
|
||||
SHA1_HMAC_KEY_LEN, SHA1_HASH_LEN, sizeof(SHA1_CTX), SHA1_HMAC_BLOCK_LEN,
|
||||
SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_key_sha1 = {
|
||||
CRYPTO_SHA1_KPDK, "Keyed SHA1",
|
||||
NULL_HMAC_KEY_LEN, SHA1_KPDK_HASH_LEN, sizeof(SHA1_CTX), 0,
|
||||
SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int
|
||||
};
|
||||
|
||||
/*
|
||||
* And now for auth.
|
||||
*/
|
||||
static void
|
||||
SHA1Init_int(void *ctx)
|
||||
{
|
||||
SHA1Init(ctx);
|
||||
}
|
||||
|
||||
static int
|
||||
SHA1Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
SHA1Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
SHA1Final_int(u_int8_t *blk, void *ctx)
|
||||
{
|
||||
SHA1Final(blk, ctx);
|
||||
}
|
109
sys/opencrypto/xform_sha2.c
Normal file
109
sys/opencrypto/xform_sha2.c
Normal file
@ -0,0 +1,109 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <crypto/sha2/sha256.h>
|
||||
#include <crypto/sha2/sha384.h>
|
||||
#include <crypto/sha2/sha512.h>
|
||||
#include <opencrypto/xform_auth.h>
|
||||
|
||||
static int SHA256Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
static int SHA384Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
static int SHA512Update_int(void *, const u_int8_t *, u_int16_t);
|
||||
|
||||
/* Authentication instances */
|
||||
struct auth_hash auth_hash_hmac_sha2_256 = {
|
||||
CRYPTO_SHA2_256_HMAC, "HMAC-SHA2-256",
|
||||
SHA2_256_HMAC_KEY_LEN, SHA2_256_HASH_LEN, sizeof(SHA256_CTX),
|
||||
SHA2_256_HMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) SHA256_Init, NULL, NULL, SHA256Update_int,
|
||||
(void (*)(u_int8_t *, void *)) SHA256_Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_hmac_sha2_384 = {
|
||||
CRYPTO_SHA2_384_HMAC, "HMAC-SHA2-384",
|
||||
SHA2_384_HMAC_KEY_LEN, SHA2_384_HASH_LEN, sizeof(SHA384_CTX),
|
||||
SHA2_384_HMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) SHA384_Init, NULL, NULL, SHA384Update_int,
|
||||
(void (*)(u_int8_t *, void *)) SHA384_Final
|
||||
};
|
||||
|
||||
struct auth_hash auth_hash_hmac_sha2_512 = {
|
||||
CRYPTO_SHA2_512_HMAC, "HMAC-SHA2-512",
|
||||
SHA2_512_HMAC_KEY_LEN, SHA2_512_HASH_LEN, sizeof(SHA512_CTX),
|
||||
SHA2_512_HMAC_BLOCK_LEN,
|
||||
(void (*)(void *)) SHA512_Init, NULL, NULL, SHA512Update_int,
|
||||
(void (*)(u_int8_t *, void *)) SHA512_Final
|
||||
};
|
||||
|
||||
/*
|
||||
* And now for auth.
|
||||
*/
|
||||
static int
|
||||
SHA256Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
SHA256_Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SHA384Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
SHA384_Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SHA512Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
|
||||
{
|
||||
SHA512_Update(ctx, buf, len);
|
||||
return 0;
|
||||
}
|
117
sys/opencrypto/xform_skipjack.c
Normal file
117
sys/opencrypto/xform_skipjack.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
|
||||
/*-
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr),
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de) and
|
||||
* Damien Miller (djm@mindrot.org).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Additional features in 1999 by Angelos D. Keromytis.
|
||||
*
|
||||
* AES XTS implementation in 2008 by Damien Miller
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
|
||||
* Angelos D. Keromytis and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 2001, Angelos D. Keromytis.
|
||||
*
|
||||
* Copyright (C) 2008, Damien Miller
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <opencrypto/skipjack.h>
|
||||
#include <opencrypto/xform_enc.h>
|
||||
|
||||
static int skipjack_setkey(u_int8_t **, u_int8_t *, int);
|
||||
static void skipjack_encrypt(caddr_t, u_int8_t *);
|
||||
static void skipjack_decrypt(caddr_t, u_int8_t *);
|
||||
static void skipjack_zerokey(u_int8_t **);
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_skipjack = {
|
||||
CRYPTO_SKIPJACK_CBC, "Skipjack",
|
||||
SKIPJACK_BLOCK_LEN, SKIPJACK_BLOCK_LEN, SKIPJACK_MIN_KEY,
|
||||
SKIPJACK_MAX_KEY,
|
||||
skipjack_encrypt,
|
||||
skipjack_decrypt, skipjack_setkey,
|
||||
skipjack_zerokey,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
skipjack_encrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
skipjack_forwards(blk, blk, (u_int8_t **) key);
|
||||
}
|
||||
|
||||
static void
|
||||
skipjack_decrypt(caddr_t key, u_int8_t *blk)
|
||||
{
|
||||
skipjack_backwards(blk, blk, (u_int8_t **) key);
|
||||
}
|
||||
|
||||
static int
|
||||
skipjack_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* NB: allocate all the memory that's needed at once */
|
||||
*sched = KMALLOC(10 * (sizeof(u_int8_t *) + 0x100),
|
||||
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
|
||||
if (*sched != NULL) {
|
||||
u_int8_t** key_tables = (u_int8_t**) *sched;
|
||||
u_int8_t* table = (u_int8_t*) &key_tables[10];
|
||||
int k;
|
||||
|
||||
for (k = 0; k < 10; k++) {
|
||||
key_tables[k] = table;
|
||||
table += 0x100;
|
||||
}
|
||||
subkey_table_gen(key, (u_int8_t **) *sched);
|
||||
err = 0;
|
||||
} else
|
||||
err = ENOMEM;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
skipjack_zerokey(u_int8_t **sched)
|
||||
{
|
||||
bzero(*sched, 10 * (sizeof(u_int8_t *) + 0x100));
|
||||
KFREE(*sched, M_CRYPTO_DATA);
|
||||
*sched = NULL;
|
||||
}
|
48
sys/opencrypto/xform_userland.h
Normal file
48
sys/opencrypto/xform_userland.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Allan Jude <allanjude@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_XFORM_USERLAND_H_
|
||||
#define _CRYPTO_XFORM_USERLAND_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/systm.h>
|
||||
#define KMALLOC(size, type, flags) malloc(size, type, flags)
|
||||
#define KFREE(ptr, type) free(ptr, type)
|
||||
#else /* not _KERNEL */
|
||||
#ifdef _STAND
|
||||
#include <stand.h>
|
||||
#else /* !_STAND */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif /* _STAND */
|
||||
#define KMALLOC(size, type, flags) malloc(size)
|
||||
#define KFREE(ptr, type) free(ptr)
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
||||
#endif /* _CRYPTO_XFORM_USERLAND_H_ */
|
@ -316,8 +316,20 @@ booke_init(uint32_t arg1, uint32_t arg2)
|
||||
|
||||
ret = powerpc_init(dtbp, 0, 0, mdp);
|
||||
|
||||
/* Enable L1 caches */
|
||||
/* Default to 32 byte cache line size. */
|
||||
switch ((mfpvr()) >> 16) {
|
||||
case FSL_E500mc:
|
||||
case FSL_E5500:
|
||||
case FSL_E6500:
|
||||
cacheline_size = 64;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enable caches */
|
||||
booke_enable_l1_cache();
|
||||
booke_enable_l2_cache();
|
||||
|
||||
booke_enable_bpred();
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ bp_ntlb1s:
|
||||
|
||||
.globl bp_tlb1
|
||||
bp_tlb1:
|
||||
.space 4 * 3 * 16
|
||||
.space 4 * 3 * 64
|
||||
|
||||
.globl bp_tlb1_end
|
||||
bp_tlb1_end:
|
||||
@ -657,77 +657,6 @@ __boot_page_padding:
|
||||
/* locore subroutines */
|
||||
/************************************************************************/
|
||||
|
||||
/*
|
||||
* void tid_flush(tlbtid_t tid);
|
||||
*
|
||||
* Invalidate all TLB0 entries which match the given TID. Note this is
|
||||
* dedicated for cases when invalidation(s) should NOT be propagated to other
|
||||
* CPUs.
|
||||
*
|
||||
* void tid_flush(tlbtid_t tid, int tlb0_ways, int tlb0_entries_per_way);
|
||||
*
|
||||
* XXX: why isn't this in C?
|
||||
*/
|
||||
ENTRY(tid_flush)
|
||||
cmpwi %r3, TID_KERNEL
|
||||
beq tid_flush_end /* don't evict kernel translations */
|
||||
|
||||
/* Disable interrupts */
|
||||
mfmsr %r10
|
||||
wrteei 0
|
||||
|
||||
li %r6, 0 /* ways counter */
|
||||
loop_ways:
|
||||
li %r7, 0 /* entries [per way] counter */
|
||||
loop_entries:
|
||||
/* Select TLB0 and ESEL (way) */
|
||||
lis %r8, MAS0_TLBSEL0@h
|
||||
rlwimi %r8, %r6, 16, 14, 15
|
||||
mtspr SPR_MAS0, %r8
|
||||
isync
|
||||
|
||||
/* Select EPN (entry within the way) */
|
||||
rlwinm %r8, %r7, 12, 13, 19
|
||||
mtspr SPR_MAS2, %r8
|
||||
isync
|
||||
tlbre
|
||||
|
||||
/* Check if valid entry */
|
||||
mfspr %r8, SPR_MAS1
|
||||
andis. %r9, %r8, MAS1_VALID@h
|
||||
beq next_entry /* invalid entry */
|
||||
|
||||
/* Check if this is our TID */
|
||||
rlwinm %r9, %r8, 16, 24, 31
|
||||
|
||||
cmplw %r9, %r3
|
||||
bne next_entry /* not our TID */
|
||||
|
||||
/* Clear VALID bit */
|
||||
rlwinm %r8, %r8, 0, 1, 31
|
||||
mtspr SPR_MAS1, %r8
|
||||
isync
|
||||
tlbwe
|
||||
isync
|
||||
msync
|
||||
|
||||
next_entry:
|
||||
addi %r7, %r7, 1
|
||||
cmpw %r7, %r5
|
||||
bne loop_entries
|
||||
|
||||
/* Next way */
|
||||
addi %r6, %r6, 1
|
||||
cmpw %r6, %r4
|
||||
bne loop_ways
|
||||
|
||||
/* Restore MSR (possibly re-enable interrupts) */
|
||||
mtmsr %r10
|
||||
isync
|
||||
|
||||
tid_flush_end:
|
||||
blr
|
||||
|
||||
/*
|
||||
* Cache disable/enable/inval sequences according
|
||||
* to section 2.16 of E500CORE RM.
|
||||
@ -801,6 +730,113 @@ ENTRY(icache_enable)
|
||||
isync
|
||||
blr
|
||||
|
||||
/*
|
||||
* L2 cache disable/enable/inval sequences for E500mc.
|
||||
*/
|
||||
|
||||
ENTRY(l2cache_inval)
|
||||
mfspr %r3, SPR_L2CSR0
|
||||
oris %r3, %r3, (L2CSR0_L2FI | L2CSR0_L2LFC)@h
|
||||
ori %r3, %r3, (L2CSR0_L2FI | L2CSR0_L2LFC)@l
|
||||
isync
|
||||
mtspr SPR_L2CSR0, %r3
|
||||
isync
|
||||
1: mfspr %r3, SPR_L2CSR0
|
||||
andis. %r3, %r3, L2CSR0_L2FI@h
|
||||
bne 1b
|
||||
blr
|
||||
|
||||
ENTRY(l2cache_enable)
|
||||
mfspr %r3, SPR_L2CSR0
|
||||
oris %r3, %r3, (L2CSR0_L2E | L2CSR0_L2PE)@h
|
||||
isync
|
||||
mtspr SPR_L2CSR0, %r3
|
||||
isync
|
||||
blr
|
||||
|
||||
/*
|
||||
* Branch predictor setup.
|
||||
*/
|
||||
ENTRY(bpred_enable)
|
||||
mfspr %r3, SPR_BUCSR
|
||||
ori %r3, %r3, BUCSR_BBFI
|
||||
isync
|
||||
mtspr SPR_BUCSR, %r3
|
||||
isync
|
||||
ori %r3, %r3, BUCSR_BPEN
|
||||
isync
|
||||
mtspr SPR_BUCSR, %r3
|
||||
isync
|
||||
blr
|
||||
|
||||
ENTRY(dataloss_erratum_access)
|
||||
/* Lock two cache lines into I-Cache */
|
||||
sync
|
||||
mfspr %r11, SPR_L1CSR1
|
||||
rlwinm %r11, %r11, 0, ~L1CSR1_ICUL
|
||||
sync
|
||||
isync
|
||||
mtspr SPR_L1CSR1, %r11
|
||||
isync
|
||||
|
||||
mflr %r9
|
||||
bl 1f
|
||||
.long 2f-.
|
||||
1:
|
||||
mflr %r5
|
||||
lwz %r8, 0(%r5)
|
||||
mtlr %r9
|
||||
add %r8, %r8, %r5
|
||||
icbtls 0, 0, %r8
|
||||
addi %r9, %r8, 64
|
||||
|
||||
sync
|
||||
mfspr %r11, SPR_L1CSR1
|
||||
3: andi. %r11, %r11, L1CSR1_ICUL
|
||||
bne 3b
|
||||
|
||||
icbtls 0, 0, %r9
|
||||
|
||||
sync
|
||||
mfspr %r11, SPR_L1CSR1
|
||||
3: andi. %r11, %r11, L1CSR1_ICUL
|
||||
bne 3b
|
||||
|
||||
b 2f
|
||||
.align 6
|
||||
/* Inside a locked cacheline, wait a while, write, then wait a while */
|
||||
2: sync
|
||||
|
||||
mfspr %r5, TBR_TBL
|
||||
4: addis %r11, %r5, 0x100000@h /* wait around one million timebase ticks */
|
||||
mfspr %r5, TBR_TBL
|
||||
subf. %r5, %r5, %r11
|
||||
bgt 4b
|
||||
|
||||
stw %r4, 0(%r3)
|
||||
|
||||
mfspr %r5, TBR_TBL
|
||||
4: addis %r11, %r5, 0x100000@h /* wait around one million timebase ticks */
|
||||
mfspr %r5, TBR_TBL
|
||||
subf. %r5, %r5, %r11
|
||||
bgt 4b
|
||||
|
||||
sync
|
||||
|
||||
/*
|
||||
* Fill out the rest of this cache line and the next with nops,
|
||||
* to ensure that nothing outside the locked area will be
|
||||
* fetched due to a branch.
|
||||
*/
|
||||
.rept 19
|
||||
nop
|
||||
.endr
|
||||
|
||||
icblc 0, 0, %r8
|
||||
icblc 0, 0, %r9
|
||||
|
||||
blr
|
||||
|
||||
/*
|
||||
* int setfault()
|
||||
*
|
||||
|
@ -27,9 +27,15 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/machdep.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
@ -42,6 +48,7 @@ extern void icache_enable(void);
|
||||
extern void icache_inval(void);
|
||||
extern void l2cache_enable(void);
|
||||
extern void l2cache_inval(void);
|
||||
extern void bpred_enable(void);
|
||||
|
||||
void
|
||||
booke_init_tlb(vm_paddr_t fdt_immr_pa)
|
||||
@ -79,7 +86,6 @@ booke_enable_l1_cache(void)
|
||||
(csr & L1CSR1_ICE) ? "en" : "dis");
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
booke_enable_l2_cache(void)
|
||||
{
|
||||
@ -102,55 +108,18 @@ booke_enable_l2_cache(void)
|
||||
}
|
||||
|
||||
void
|
||||
booke_enable_l3_cache(void)
|
||||
booke_enable_bpred(void)
|
||||
{
|
||||
uint32_t csr, size, ver;
|
||||
uint32_t csr;
|
||||
|
||||
/* Enable L3 CoreNet Platform Cache (CPC) */
|
||||
ver = SVR_VER(mfspr(SPR_SVR));
|
||||
if (ver == SVR_P2041 || ver == SVR_P2041E || ver == SVR_P3041 ||
|
||||
ver == SVR_P3041E || ver == SVR_P5020 || ver == SVR_P5020E) {
|
||||
csr = ccsr_read4(OCP85XX_CPC_CSR0);
|
||||
if ((csr & OCP85XX_CPC_CSR0_CE) == 0) {
|
||||
l3cache_inval();
|
||||
l3cache_enable();
|
||||
}
|
||||
|
||||
csr = ccsr_read4(OCP85XX_CPC_CSR0);
|
||||
if ((boothowto & RB_VERBOSE) != 0 ||
|
||||
(csr & OCP85XX_CPC_CSR0_CE) == 0) {
|
||||
size = OCP85XX_CPC_CFG0_SZ_K(ccsr_read4(OCP85XX_CPC_CFG0));
|
||||
printf("L3 Corenet Platform Cache: %d KB %sabled\n",
|
||||
size, (csr & OCP85XX_CPC_CSR0_CE) == 0 ?
|
||||
"dis" : "en");
|
||||
}
|
||||
}
|
||||
bpred_enable();
|
||||
csr = mfspr(SPR_BUCSR);
|
||||
if ((boothowto & RB_VERBOSE) != 0 || (csr & BUCSR_BPEN) == 0)
|
||||
printf("Branch Predictor %sabled\n",
|
||||
(csr & BUCSR_BPEN) ? "en" : "dis");
|
||||
}
|
||||
|
||||
void
|
||||
booke_disable_l2_cache(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
l3cache_inval(void)
|
||||
{
|
||||
|
||||
/* Flash invalidate the CPC and clear all the locks */
|
||||
ccsr_write4(OCP85XX_CPC_CSR0, OCP85XX_CPC_CSR0_FI |
|
||||
OCP85XX_CPC_CSR0_LFC);
|
||||
while (ccsr_read4(OCP85XX_CPC_CSR0) & (OCP85XX_CPC_CSR0_FI |
|
||||
OCP85XX_CPC_CSR0_LFC))
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
l3cache_enable(void)
|
||||
{
|
||||
|
||||
ccsr_write4(OCP85XX_CPC_CSR0, OCP85XX_CPC_CSR0_CE |
|
||||
OCP85XX_CPC_CSR0_PE);
|
||||
/* Read back to sync write */
|
||||
ccsr_read4(OCP85XX_CPC_CSR0);
|
||||
}
|
||||
#endif
|
||||
|
@ -161,7 +161,6 @@ unsigned int kernel_ptbls; /* Number of KVA ptbls. */
|
||||
#define PMAP_REMOVE_DONE(pmap) \
|
||||
((pmap) != kernel_pmap && (pmap)->pm_stats.resident_count == 0)
|
||||
|
||||
extern void tid_flush(tlbtid_t tid, int tlb0_ways, int tlb0_entries_per_way);
|
||||
extern int elf32_nxstack;
|
||||
|
||||
/**************************************************************************/
|
||||
@ -195,6 +194,7 @@ static unsigned int tlb1_idx;
|
||||
static vm_offset_t tlb1_map_base = VM_MAX_KERNEL_ADDRESS;
|
||||
|
||||
static tlbtid_t tid_alloc(struct pmap *);
|
||||
static void tid_flush(tlbtid_t tid);
|
||||
|
||||
static void tlb_print_entry(int, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
|
||||
@ -2235,8 +2235,17 @@ mmu_booke_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size)
|
||||
static void
|
||||
mmu_booke_zero_page(mmu_t mmu, vm_page_t m)
|
||||
{
|
||||
vm_offset_t off, va;
|
||||
|
||||
mmu_booke_zero_page_area(mmu, m, 0, PAGE_SIZE);
|
||||
mtx_lock(&zero_page_mutex);
|
||||
va = zero_page_va;
|
||||
|
||||
mmu_booke_kenter(mmu, va, VM_PAGE_TO_PHYS(m));
|
||||
for (off = 0; off < PAGE_SIZE; off += cacheline_size)
|
||||
__asm __volatile("dcbzl 0,%0" :: "r"(va + off));
|
||||
mmu_booke_kremove(mmu, va);
|
||||
|
||||
mtx_unlock(&zero_page_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2915,7 +2924,7 @@ tid_alloc(pmap_t pmap)
|
||||
tidbusy[thiscpu][tid]->pm_tid[thiscpu] = TID_NONE;
|
||||
|
||||
/* Flush all entries from TLB0 matching this TID. */
|
||||
tid_flush(tid, tlb0_ways, tlb0_entries_per_way);
|
||||
tid_flush(tid);
|
||||
}
|
||||
|
||||
tidbusy[thiscpu][tid] = pmap;
|
||||
@ -3426,3 +3435,48 @@ tlb1_iomapped(int i, vm_paddr_t pa, vm_size_t size, vm_offset_t *va)
|
||||
*va = (tlb1[i].mas2 & MAS2_EPN_MASK) + (pa - pa_start);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Invalidate all TLB0 entries which match the given TID. Note this is
|
||||
* dedicated for cases when invalidations should NOT be propagated to other
|
||||
* CPUs.
|
||||
*/
|
||||
static void
|
||||
tid_flush(tlbtid_t tid)
|
||||
{
|
||||
register_t msr;
|
||||
uint32_t mas0, mas1, mas2;
|
||||
int entry, way;
|
||||
|
||||
|
||||
/* Don't evict kernel translations */
|
||||
if (tid == TID_KERNEL)
|
||||
return;
|
||||
|
||||
msr = mfmsr();
|
||||
__asm __volatile("wrteei 0");
|
||||
|
||||
for (way = 0; way < TLB0_WAYS; way++)
|
||||
for (entry = 0; entry < TLB0_ENTRIES_PER_WAY; entry++) {
|
||||
|
||||
mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(way);
|
||||
mtspr(SPR_MAS0, mas0);
|
||||
__asm __volatile("isync");
|
||||
|
||||
mas2 = entry << MAS2_TLB0_ENTRY_IDX_SHIFT;
|
||||
mtspr(SPR_MAS2, mas2);
|
||||
|
||||
__asm __volatile("isync; tlbre");
|
||||
|
||||
mas1 = mfspr(SPR_MAS1);
|
||||
|
||||
if (!(mas1 & MAS1_VALID))
|
||||
continue;
|
||||
if (((mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT) != tid)
|
||||
continue;
|
||||
mas1 &= ~MAS1_VALID;
|
||||
mtspr(SPR_MAS1, mas1);
|
||||
__asm __volatile("isync; tlbwe; isync; msync");
|
||||
}
|
||||
mtmsr(msr);
|
||||
}
|
||||
|
@ -32,18 +32,26 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/systm.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/machdep.h>
|
||||
#include <machine/pio.h>
|
||||
#include <machine/spr.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
||||
#include <powerpc/mpc85xx/mpc85xx.h>
|
||||
|
||||
|
||||
@ -249,3 +257,166 @@ law_pci_target(struct resource *res, int *trgt_mem, int *trgt_io)
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static void
|
||||
l3cache_inval(void)
|
||||
{
|
||||
|
||||
/* Flash invalidate the CPC and clear all the locks */
|
||||
ccsr_write4(OCP85XX_CPC_CSR0, OCP85XX_CPC_CSR0_FI |
|
||||
OCP85XX_CPC_CSR0_LFC);
|
||||
while (ccsr_read4(OCP85XX_CPC_CSR0) & (OCP85XX_CPC_CSR0_FI |
|
||||
OCP85XX_CPC_CSR0_LFC))
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
l3cache_enable(void)
|
||||
{
|
||||
|
||||
ccsr_write4(OCP85XX_CPC_CSR0, OCP85XX_CPC_CSR0_CE |
|
||||
OCP85XX_CPC_CSR0_PE);
|
||||
/* Read back to sync write */
|
||||
ccsr_read4(OCP85XX_CPC_CSR0);
|
||||
}
|
||||
|
||||
void
|
||||
mpc85xx_enable_l3_cache(void)
|
||||
{
|
||||
uint32_t csr, size, ver;
|
||||
|
||||
/* Enable L3 CoreNet Platform Cache (CPC) */
|
||||
ver = SVR_VER(mfspr(SPR_SVR));
|
||||
if (ver == SVR_P2041 || ver == SVR_P2041E || ver == SVR_P3041 ||
|
||||
ver == SVR_P3041E || ver == SVR_P5020 || ver == SVR_P5020E) {
|
||||
csr = ccsr_read4(OCP85XX_CPC_CSR0);
|
||||
if ((csr & OCP85XX_CPC_CSR0_CE) == 0) {
|
||||
l3cache_inval();
|
||||
l3cache_enable();
|
||||
}
|
||||
|
||||
csr = ccsr_read4(OCP85XX_CPC_CSR0);
|
||||
if ((boothowto & RB_VERBOSE) != 0 ||
|
||||
(csr & OCP85XX_CPC_CSR0_CE) == 0) {
|
||||
size = OCP85XX_CPC_CFG0_SZ_K(ccsr_read4(OCP85XX_CPC_CFG0));
|
||||
printf("L3 Corenet Platform Cache: %d KB %sabled\n",
|
||||
size, (csr & OCP85XX_CPC_CSR0_CE) == 0 ?
|
||||
"dis" : "en");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mpc85xx_dataloss_erratum_spr976(void)
|
||||
{
|
||||
uint32_t svr = SVR_VER(mfspr(SPR_SVR));
|
||||
|
||||
/* Ignore whether it's the E variant */
|
||||
svr &= ~0x8;
|
||||
|
||||
if (svr != SVR_P3041 && svr != SVR_P4040 &&
|
||||
svr != SVR_P4080 && svr != SVR_P5020)
|
||||
return;
|
||||
|
||||
mb();
|
||||
isync();
|
||||
mtspr(976, (mfspr(976) & ~0x1f8) | 0x48);
|
||||
isync();
|
||||
}
|
||||
|
||||
static vm_offset_t
|
||||
mpc85xx_map_dcsr(void)
|
||||
{
|
||||
phandle_t node;
|
||||
u_long b, s;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Try to access the dcsr node directly i.e. through /aliases/.
|
||||
*/
|
||||
if ((node = OF_finddevice("dcsr")) != -1)
|
||||
if (fdt_is_compatible_strict(node, "fsl,dcsr"))
|
||||
goto moveon;
|
||||
/*
|
||||
* Find the node the long way.
|
||||
*/
|
||||
if ((node = OF_finddevice("/")) == -1)
|
||||
return (ENXIO);
|
||||
|
||||
if ((node = ofw_bus_find_compatible(node, "fsl,dcsr")) == 0)
|
||||
return (ENXIO);
|
||||
|
||||
moveon:
|
||||
err = fdt_get_range(node, 0, &b, &s);
|
||||
|
||||
if (err != 0)
|
||||
return (err);
|
||||
|
||||
#ifdef QORIQ_DPAA
|
||||
law_enable(OCP85XX_TGTIF_DCSR, b, 0x400000);
|
||||
#endif
|
||||
return pmap_early_io_map(b, 0x400000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
mpc85xx_fix_errata(vm_offset_t va_ccsr)
|
||||
{
|
||||
uint32_t svr = SVR_VER(mfspr(SPR_SVR));
|
||||
vm_offset_t va_dcsr;
|
||||
|
||||
/* Ignore whether it's the E variant */
|
||||
svr &= ~0x8;
|
||||
|
||||
if (svr != SVR_P3041 && svr != SVR_P4040 &&
|
||||
svr != SVR_P4080 && svr != SVR_P5020)
|
||||
return;
|
||||
|
||||
if (mfmsr() & PSL_EE)
|
||||
return;
|
||||
|
||||
/*
|
||||
* dcsr region need to be mapped thus patch can refer to.
|
||||
* Align dcsr right after ccsbar.
|
||||
*/
|
||||
va_dcsr = mpc85xx_map_dcsr();
|
||||
if (va_dcsr == 0)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* As A004510 errata specify, special purpose register 976
|
||||
* SPR976[56:60] = 6'b001001 must be set. e500mc core reference manual
|
||||
* does not document SPR976 register.
|
||||
*/
|
||||
mpc85xx_dataloss_erratum_spr976();
|
||||
|
||||
/*
|
||||
* Specific settings in the CCF and core platform cache (CPC)
|
||||
* are required to reconfigure the CoreNet coherency fabric.
|
||||
* The register settings that should be updated are described
|
||||
* in errata and relay on base address, offset and updated value.
|
||||
* Special conditions must be used to update these registers correctly.
|
||||
*/
|
||||
dataloss_erratum_access(va_dcsr + 0xb0e08, 0xe0201800);
|
||||
dataloss_erratum_access(va_dcsr + 0xb0e18, 0xe0201800);
|
||||
dataloss_erratum_access(va_dcsr + 0xb0e38, 0xe0400000);
|
||||
dataloss_erratum_access(va_dcsr + 0xb0008, 0x00900000);
|
||||
dataloss_erratum_access(va_dcsr + 0xb0e40, 0xe00a0000);
|
||||
|
||||
switch (svr) {
|
||||
case SVR_P5020:
|
||||
dataloss_erratum_access(va_ccsr + 0x18600, 0xc0000000);
|
||||
break;
|
||||
case SVR_P4040:
|
||||
case SVR_P4080:
|
||||
dataloss_erratum_access(va_ccsr + 0x18600, 0xff000000);
|
||||
break;
|
||||
case SVR_P3041:
|
||||
dataloss_erratum_access(va_ccsr + 0x18600, 0xf0000000);
|
||||
}
|
||||
dataloss_erratum_access(va_ccsr + 0x10f00, 0x415e5000);
|
||||
dataloss_erratum_access(va_ccsr + 0x11f00, 0x415e5000);
|
||||
|
||||
err:
|
||||
return;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user