Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137936984
D36745.id111075.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
29 KB
Referenced Files
None
Subscribers
None
D36745.id111075.diff
View Options
diff --git a/bin/stty/stty.1 b/bin/stty/stty.1
--- a/bin/stty/stty.1
+++ b/bin/stty/stty.1
@@ -32,7 +32,7 @@
.\" @(#)stty.1 8.4 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
-.Dd May 24, 2022
+.Dd September 27, 2022
.Dt STTY 1
.Os
.Sh NAME
@@ -40,7 +40,7 @@
.Nd set the options for a terminal device interface
.Sh SYNOPSIS
.Nm
-.Op Fl a | e | g
+.Op Fl a | e | g | i
.Op Fl f Ar file
.Op Ar arguments
.Sh DESCRIPTION
@@ -85,6 +85,23 @@
.Nm
to restore the current terminal state as per
.St -p1003.2 .
+.It Fl i
+Allow
+.Nm
+to change terminal settings even when executing in background
+process group (see description of the job control in
+.Xr termios 4 ) .
+.Pp
+Normally, such attempt results in kernel sending the
+.Va SIGTTOU
+signal and stopping the process until its group is returned
+to foreground.
+Using this option makes
+.Nm
+ignore
+.Va SIGTTOU .
+Note that changing terminal settings for running foreground
+job that is not prepared for it might cause inconsistencies.
.El
.Pp
The following arguments are available to set the terminal
@@ -607,9 +624,10 @@
.St -p1003.2
compatible.
The flags
-.Fl e
-and
+.Fl e ,
.Fl f
+and
+.Fl i
are
extensions to the standard.
.Sh HISTORY
diff --git a/bin/stty/stty.c b/bin/stty/stty.c
--- a/bin/stty/stty.c
+++ b/bin/stty/stty.c
@@ -47,6 +47,7 @@
#include <err.h>
#include <fcntl.h>
#include <limits.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -59,6 +60,7 @@
main(int argc, char *argv[])
{
struct info i;
+ struct sigaction sa;
enum FMT fmt;
int ch;
const char *file, *errstr = NULL;
@@ -69,8 +71,8 @@
opterr = 0;
while (optind < argc &&
- strspn(argv[optind], "-aefg") == strlen(argv[optind]) &&
- (ch = getopt(argc, argv, "aef:g")) != -1)
+ strspn(argv[optind], "-aefgi") == strlen(argv[optind]) &&
+ (ch = getopt(argc, argv, "aef:gi")) != -1)
switch(ch) {
case 'a': /* undocumented: POSIX compatibility */
fmt = POSIX;
@@ -86,6 +88,12 @@
case 'g':
fmt = GFLAG;
break;
+ case 'i':
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ if (sigaction(SIGTTOU, &sa, NULL) == -1)
+ err(1, "sigaction");
+ break;
case '?':
default:
goto args;
@@ -161,6 +169,6 @@
{
(void)fprintf(stderr,
- "usage: stty [-a | -e | -g] [-f file] [arguments]\n");
+ "usage: stty [-a | -e | -g] [-i] [-f file] [arguments]\n");
exit (1);
}
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -817,51 +817,35 @@
}
/* State of the bootstrapped DMAP page tables */
-struct pmap_bootstrap_state {
+struct dmap_bootstrap_state {
vm_offset_t va;
vm_paddr_t pa;
pt_entry_t *l1;
pt_entry_t *l2;
pt_entry_t *l3;
- pt_entry_t table_attrs;
u_int l0_slot;
u_int l1_slot;
u_int l2_slot;
vm_offset_t freemempos;
- bool dmap_valid;
-};
-
-/* The bootstrap state */
-static struct pmap_bootstrap_state bs_state = {
- .l1 = NULL,
- .l2 = NULL,
- .l3 = NULL,
- .table_attrs = TATTR_PXN_TABLE,
- .l0_slot = L0_ENTRIES,
- .l1_slot = Ln_ENTRIES,
- .l2_slot = Ln_ENTRIES,
- .dmap_valid = false,
};
static void
-pmap_bootstrap_l0_table(struct pmap_bootstrap_state *state)
+pmap_bootstrap_dmap_l0_table(struct dmap_bootstrap_state *state)
{
vm_paddr_t l1_pa;
- pd_entry_t l0e;
u_int l0_slot;
/* Link the level 0 table to a level 1 table */
l0_slot = pmap_l0_index(state->va);
if (l0_slot != state->l0_slot) {
- /*
- * Make sure we move from a low address to high address
- * before the DMAP region is ready. This ensures we never
- * modify an existing mapping until we can map from a
- * physical address to a virtual address.
- */
MPASS(state->l0_slot < l0_slot ||
- state->l0_slot == L0_ENTRIES ||
- state->dmap_valid);
+ state->l0_slot == L0_ENTRIES);
+
+ /* Create a new L0 table entry */
+ state->l0_slot = l0_slot;
+ state->l1 = (pt_entry_t *)state->freemempos;
+ memset(state->l1, 0, PAGE_SIZE);
+ state->freemempos += PAGE_SIZE;
/* Reset lower levels */
state->l2 = NULL;
@@ -869,23 +853,6 @@
state->l1_slot = Ln_ENTRIES;
state->l2_slot = Ln_ENTRIES;
- /* Check the existing L0 entry */
- state->l0_slot = l0_slot;
- if (state->dmap_valid) {
- l0e = pagetable_l0_ttbr1[l0_slot];
- if ((l0e & ATTR_DESCR_VALID) != 0) {
- MPASS((l0e & ATTR_DESCR_MASK) == L0_TABLE);
- l1_pa = l0e & ~ATTR_MASK;
- state->l1 = (pt_entry_t *)PHYS_TO_DMAP(l1_pa);
- return;
- }
- }
-
- /* Create a new L0 table entry */
- state->l1 = (pt_entry_t *)state->freemempos;
- memset(state->l1, 0, PAGE_SIZE);
- state->freemempos += PAGE_SIZE;
-
l1_pa = pmap_early_vtophys((vm_offset_t)state->l1);
MPASS((l1_pa & Ln_TABLE_MASK) == 0);
MPASS(pagetable_l0_ttbr1[l0_slot] == 0);
@@ -896,84 +863,56 @@
}
static void
-pmap_bootstrap_l1_table(struct pmap_bootstrap_state *state)
+pmap_bootstrap_dmap_l1_table(struct dmap_bootstrap_state *state)
{
vm_paddr_t l2_pa;
- pd_entry_t l1e;
u_int l1_slot;
/* Make sure there is a valid L0 -> L1 table */
- pmap_bootstrap_l0_table(state);
+ pmap_bootstrap_dmap_l0_table(state);
/* Link the level 1 table to a level 2 table */
l1_slot = pmap_l1_index(state->va);
if (l1_slot != state->l1_slot) {
- /* See pmap_bootstrap_l0_table for a description */
MPASS(state->l1_slot < l1_slot ||
- state->l1_slot == Ln_ENTRIES ||
- state->dmap_valid);
-
- /* Reset lower levels */
- state->l3 = NULL;
- state->l2_slot = Ln_ENTRIES;
-
- /* Check the existing L1 entry */
- state->l1_slot = l1_slot;
- if (state->dmap_valid) {
- l1e = state->l1[l1_slot];
- if ((l1e & ATTR_DESCR_VALID) != 0) {
- MPASS((l1e & ATTR_DESCR_MASK) == L1_TABLE);
- l2_pa = l1e & ~ATTR_MASK;
- state->l2 = (pt_entry_t *)PHYS_TO_DMAP(l2_pa);
- return;
- }
- }
+ state->l1_slot == Ln_ENTRIES);
/* Create a new L1 table entry */
+ state->l1_slot = l1_slot;
state->l2 = (pt_entry_t *)state->freemempos;
memset(state->l2, 0, PAGE_SIZE);
state->freemempos += PAGE_SIZE;
+ /* Reset lower levels */
+ state->l3 = NULL;
+ state->l2_slot = Ln_ENTRIES;
+
l2_pa = pmap_early_vtophys((vm_offset_t)state->l2);
MPASS((l2_pa & Ln_TABLE_MASK) == 0);
MPASS(state->l1[l1_slot] == 0);
- pmap_store(&state->l1[l1_slot], l2_pa | state->table_attrs |
+ pmap_store(&state->l1[l1_slot], l2_pa | TATTR_PXN_TABLE |
L1_TABLE);
}
KASSERT(state->l2 != NULL, ("%s: NULL l2", __func__));
}
static void
-pmap_bootstrap_l2_table(struct pmap_bootstrap_state *state)
+pmap_bootstrap_dmap_l2_table(struct dmap_bootstrap_state *state)
{
vm_paddr_t l3_pa;
- pd_entry_t l2e;
u_int l2_slot;
/* Make sure there is a valid L1 -> L2 table */
- pmap_bootstrap_l1_table(state);
+ pmap_bootstrap_dmap_l1_table(state);
/* Link the level 2 table to a level 3 table */
l2_slot = pmap_l2_index(state->va);
if (l2_slot != state->l2_slot) {
- /* See pmap_bootstrap_l0_table for a description */
MPASS(state->l2_slot < l2_slot ||
- state->l2_slot == Ln_ENTRIES ||
- state->dmap_valid);
-
- /* Check the existing L2 entry */
- state->l2_slot = l2_slot;
- if (state->dmap_valid) {
- l2e = state->l2[l2_slot];
- if ((l2e & ATTR_DESCR_VALID) != 0) {
- MPASS((l2e & ATTR_DESCR_MASK) == L2_TABLE);
- l3_pa = l2e & ~ATTR_MASK;
- state->l3 = (pt_entry_t *)PHYS_TO_DMAP(l3_pa);
- return;
- }
- }
+ state->l2_slot == Ln_ENTRIES);
/* Create a new L2 table entry */
+ state->l2_slot = l2_slot;
state->l3 = (pt_entry_t *)state->freemempos;
memset(state->l3, 0, PAGE_SIZE);
state->freemempos += PAGE_SIZE;
@@ -981,14 +920,14 @@
l3_pa = pmap_early_vtophys((vm_offset_t)state->l3);
MPASS((l3_pa & Ln_TABLE_MASK) == 0);
MPASS(state->l2[l2_slot] == 0);
- pmap_store(&state->l2[l2_slot], l3_pa | state->table_attrs |
+ pmap_store(&state->l2[l2_slot], l3_pa | TATTR_PXN_TABLE |
L2_TABLE);
}
KASSERT(state->l3 != NULL, ("%s: NULL l3", __func__));
}
static void
-pmap_bootstrap_l2_block(struct pmap_bootstrap_state *state, int i)
+pmap_bootstrap_dmap_l2_block(struct dmap_bootstrap_state *state, int i)
{
u_int l2_slot;
bool first;
@@ -997,7 +936,7 @@
return;
/* Make sure there is a valid L1 table */
- pmap_bootstrap_l1_table(state);
+ pmap_bootstrap_dmap_l1_table(state);
MPASS((state->va & L2_OFFSET) == 0);
for (first = true;
@@ -1023,7 +962,7 @@
}
static void
-pmap_bootstrap_l3_page(struct pmap_bootstrap_state *state, int i)
+pmap_bootstrap_dmap_l3_page(struct dmap_bootstrap_state *state, int i)
{
u_int l3_slot;
bool first;
@@ -1032,7 +971,7 @@
return;
/* Make sure there is a valid L2 table */
- pmap_bootstrap_l2_table(state);
+ pmap_bootstrap_dmap_l2_table(state);
MPASS((state->va & L3_OFFSET) == 0);
for (first = true;
@@ -1061,97 +1000,130 @@
pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t min_pa,
vm_offset_t freemempos)
{
+ struct dmap_bootstrap_state state;
int i;
dmap_phys_base = min_pa & ~L1_OFFSET;
dmap_phys_max = 0;
dmap_max_addr = 0;
- bs_state.freemempos = freemempos;
+ state.l1 = state.l2 = state.l3 = NULL;
+ state.l0_slot = L0_ENTRIES;
+ state.l1_slot = Ln_ENTRIES;
+ state.l2_slot = Ln_ENTRIES;
+ state.freemempos = freemempos;
for (i = 0; i < (physmap_idx * 2); i += 2) {
- bs_state.pa = physmap[i] & ~L3_OFFSET;
- bs_state.va = bs_state.pa - dmap_phys_base + DMAP_MIN_ADDRESS;
+ state.pa = physmap[i] & ~L3_OFFSET;
+ state.va = state.pa - dmap_phys_base + DMAP_MIN_ADDRESS;
/* Create L3 mappings at the start of the region */
- if ((bs_state.pa & L2_OFFSET) != 0)
- pmap_bootstrap_l3_page(&bs_state, i);
- MPASS(bs_state.pa <= physmap[i + 1]);
+ if ((state.pa & L2_OFFSET) != 0)
+ pmap_bootstrap_dmap_l3_page(&state, i);
+ MPASS(state.pa <= physmap[i + 1]);
if (L1_BLOCKS_SUPPORTED) {
/* Create L2 mappings at the start of the region */
- if ((bs_state.pa & L1_OFFSET) != 0)
- pmap_bootstrap_l2_block(&bs_state, i);
- MPASS(bs_state.pa <= physmap[i + 1]);
+ if ((state.pa & L1_OFFSET) != 0)
+ pmap_bootstrap_dmap_l2_block(&state, i);
+ MPASS(state.pa <= physmap[i + 1]);
/* Create the main L1 block mappings */
- for (; bs_state.va < DMAP_MAX_ADDRESS &&
- (physmap[i + 1] - bs_state.pa) >= L1_SIZE;
- bs_state.va += L1_SIZE, bs_state.pa += L1_SIZE) {
+ for (; state.va < DMAP_MAX_ADDRESS &&
+ (physmap[i + 1] - state.pa) >= L1_SIZE;
+ state.va += L1_SIZE, state.pa += L1_SIZE) {
/* Make sure there is a valid L1 table */
- pmap_bootstrap_l0_table(&bs_state);
- MPASS((bs_state.pa & L1_OFFSET) == 0);
- pmap_store(
- &bs_state.l1[pmap_l1_index(bs_state.va)],
- bs_state.pa | ATTR_DEFAULT | ATTR_S1_XN |
+ pmap_bootstrap_dmap_l0_table(&state);
+ MPASS((state.pa & L1_OFFSET) == 0);
+ pmap_store(&state.l1[pmap_l1_index(state.va)],
+ state.pa | ATTR_DEFAULT | ATTR_S1_XN |
ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) |
L1_BLOCK);
}
- MPASS(bs_state.pa <= physmap[i + 1]);
+ MPASS(state.pa <= physmap[i + 1]);
/* Create L2 mappings at the end of the region */
- pmap_bootstrap_l2_block(&bs_state, i);
+ pmap_bootstrap_dmap_l2_block(&state, i);
} else {
- while (bs_state.va < DMAP_MAX_ADDRESS &&
- (physmap[i + 1] - bs_state.pa) >= L2_SIZE) {
- pmap_bootstrap_l2_block(&bs_state, i);
+ while (state.va < DMAP_MAX_ADDRESS &&
+ (physmap[i + 1] - state.pa) >= L2_SIZE) {
+ pmap_bootstrap_dmap_l2_block(&state, i);
}
}
- MPASS(bs_state.pa <= physmap[i + 1]);
+ MPASS(state.pa <= physmap[i + 1]);
/* Create L3 mappings at the end of the region */
- pmap_bootstrap_l3_page(&bs_state, i);
- MPASS(bs_state.pa == physmap[i + 1]);
+ pmap_bootstrap_dmap_l3_page(&state, i);
+ MPASS(state.pa == physmap[i + 1]);
- if (bs_state.pa > dmap_phys_max) {
- dmap_phys_max = bs_state.pa;
- dmap_max_addr = bs_state.va;
+ if (state.pa > dmap_phys_max) {
+ dmap_phys_max = state.pa;
+ dmap_max_addr = state.va;
}
}
cpu_tlb_flushID();
- return (bs_state.freemempos);
+ return (state.freemempos);
}
static vm_offset_t
pmap_bootstrap_l2(vm_offset_t l1pt, vm_offset_t va, vm_offset_t l2_start)
{
+ vm_offset_t l2pt;
+ vm_paddr_t pa;
+ pd_entry_t *l1;
+ u_int l1_slot;
+
KASSERT((va & L1_OFFSET) == 0, ("Invalid virtual address"));
- /* Leave bs_state.pa as it's only needed to bootstrap blocks and pages*/
- bs_state.va = va;
- bs_state.freemempos = l2_start;
+ l1 = (pd_entry_t *)l1pt;
+ l1_slot = pmap_l1_index(va);
+ l2pt = l2_start;
- for (; bs_state.va < VM_MAX_KERNEL_ADDRESS; bs_state.va += L1_SIZE)
- pmap_bootstrap_l1_table(&bs_state);
+ for (; va < VM_MAX_KERNEL_ADDRESS; l1_slot++, va += L1_SIZE) {
+ KASSERT(l1_slot < Ln_ENTRIES, ("Invalid L1 index"));
+
+ pa = pmap_early_vtophys(l2pt);
+ pmap_store(&l1[l1_slot],
+ (pa & ~Ln_TABLE_MASK) | L1_TABLE);
+ l2pt += PAGE_SIZE;
+ }
- return (bs_state.freemempos);
+ /* Clean the L2 page table */
+ memset((void *)l2_start, 0, l2pt - l2_start);
+
+ return l2pt;
}
static vm_offset_t
pmap_bootstrap_l3(vm_offset_t l1pt, vm_offset_t va, vm_offset_t l3_start)
{
+ vm_offset_t l3pt;
+ vm_paddr_t pa;
+ pd_entry_t *l2;
+ u_int l2_slot;
+
KASSERT((va & L2_OFFSET) == 0, ("Invalid virtual address"));
- /* Leave bs_state.pa as it's only needed to bootstrap blocks and pages*/
- bs_state.va = va;
- bs_state.freemempos = l3_start;
+ l2 = pmap_l2(kernel_pmap, va);
+ l2 = (pd_entry_t *)rounddown2((uintptr_t)l2, PAGE_SIZE);
+ l2_slot = pmap_l2_index(va);
+ l3pt = l3_start;
+
+ for (; va < VM_MAX_KERNEL_ADDRESS; l2_slot++, va += L2_SIZE) {
+ KASSERT(l2_slot < Ln_ENTRIES, ("Invalid L2 index"));
+
+ pa = pmap_early_vtophys(l3pt);
+ pmap_store(&l2[l2_slot],
+ (pa & ~Ln_TABLE_MASK) | ATTR_S1_UXN | L2_TABLE);
+ l3pt += PAGE_SIZE;
+ }
- for (; bs_state.va < VM_MAX_KERNEL_ADDRESS; bs_state.va += L2_SIZE)
- pmap_bootstrap_l2_table(&bs_state);
+ /* Clean the L2 page table */
+ memset((void *)l3_start, 0, l3pt - l3_start);
- return (bs_state.freemempos);
+ return l3pt;
}
/*
@@ -1209,12 +1181,6 @@
/* Create a direct map region early so we can use it for pa -> va */
freemempos = pmap_bootstrap_dmap(l1pt, min_pa, freemempos);
- bs_state.dmap_valid = true;
- /*
- * We only use PXN when we know nothing will be executed from it, e.g.
- * the DMAP region.
- */
- bs_state.table_attrs &= ~TATTR_PXN_TABLE;
start_pa = pa = KERNBASE - kern_delta;
diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c
--- a/sys/net/if_epair.c
+++ b/sys/net/if_epair.c
@@ -184,13 +184,39 @@
if_rele(sc->ifp);
}
-static struct epair_queue *
-epair_select_queue(struct epair_softc *sc, const struct mbuf *m)
+static int
+epair_menq(struct mbuf *m, struct epair_softc *osc)
{
+ struct ifnet *ifp, *oifp;
+ int len, ret;
+ int ridx;
+ short mflags;
+ struct epair_queue *q = NULL;
uint32_t bucket;
#ifdef RSS
struct ether_header *eh;
+#endif
+
+ /*
+ * I know this looks weird. We pass the "other sc" as we need that one
+ * and can get both ifps from it as well.
+ */
+ oifp = osc->ifp;
+ ifp = osc->oifp;
+
+ M_ASSERTPKTHDR(m);
+ epair_clear_mbuf(m);
+ if_setrcvif(m, oifp);
+ M_SETFIB(m, oifp->if_fib);
+
+ /* Save values as once the mbuf is queued, it's not ours anymore. */
+ len = m->m_pkthdr.len;
+ mflags = m->m_flags;
+
+ MPASS(m->m_nextpkt == NULL);
+ MPASS((m->m_pkthdr.csum_flags & CSUM_SND_TAG) == 0);
+#ifdef RSS
ret = rss_m2bucket(m, &bucket);
if (ret) {
/* Actually hash the packet. */
@@ -212,47 +238,11 @@
break;
}
}
- bucket %= sc->num_queues;
+ bucket %= osc->num_queues;
#else
bucket = 0;
#endif
- return (&sc->queues[bucket]);
-}
-
-static void
-epair_prepare_mbuf(struct mbuf *m, struct ifnet *src_ifp)
-{
- M_ASSERTPKTHDR(m);
- epair_clear_mbuf(m);
- if_setrcvif(m, src_ifp);
- M_SETFIB(m, src_ifp->if_fib);
-
- MPASS(m->m_nextpkt == NULL);
- MPASS((m->m_pkthdr.csum_flags & CSUM_SND_TAG) == 0);
-}
-
-static void
-epair_menq(struct mbuf *m, struct epair_softc *osc)
-{
- struct ifnet *ifp, *oifp;
- int len, ret;
- int ridx;
- short mflags;
-
- /*
- * I know this looks weird. We pass the "other sc" as we need that one
- * and can get both ifps from it as well.
- */
- oifp = osc->ifp;
- ifp = osc->oifp;
-
- epair_prepare_mbuf(m, oifp);
-
- /* Save values as once the mbuf is queued, it's not ours anymore. */
- len = m->m_pkthdr.len;
- mflags = m->m_flags;
-
- struct epair_queue *q = epair_select_queue(osc, m);
+ q = &osc->queues[bucket];
atomic_set_long(&q->state, (1 << BIT_MBUF_QUEUED));
ridx = atomic_load_int(&q->ridx);
@@ -261,7 +251,7 @@
/* Ring is full. */
if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
m_freem(m);
- return;
+ return (0);
}
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
@@ -277,7 +267,9 @@
if_inc_counter(oifp, IFCOUNTER_IPACKETS, 1);
if (!atomic_testandset_long(&q->state, BIT_QUEUE_TASK))
- taskqueue_enqueue(epair_tasks.tq[q->id], &q->tx_task);
+ taskqueue_enqueue(epair_tasks.tq[bucket], &q->tx_task);
+
+ return (0);
}
static void
@@ -312,7 +304,7 @@
continue;
}
- epair_menq(m, sc);
+ (void) epair_menq(m, sc);
}
}
@@ -321,6 +313,7 @@
{
struct epair_softc *sc;
struct ifnet *oifp;
+ int error;
#ifdef ALTQ
int len;
short mflags;
@@ -365,7 +358,6 @@
#ifdef ALTQ
len = m->m_pkthdr.len;
mflags = m->m_flags;
- int error = 0;
/* Support ALTQ via the classic if_start() path. */
IF_LOCK(&ifp->if_snd);
@@ -385,8 +377,8 @@
IF_UNLOCK(&ifp->if_snd);
#endif
- epair_menq(m, oifp->if_softc);
- return (0);
+ error = epair_menq(m, oifp->if_softc);
+ return (error);
}
static void
@@ -615,23 +607,15 @@
free(sc, M_EPAIR);
}
-static void
-epair_set_state(struct ifnet *ifp, bool running)
-{
- if (running) {
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- if_link_state_change(ifp, LINK_STATE_UP);
- } else {
- if_link_state_change(ifp, LINK_STATE_DOWN);
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- }
-}
-
static int
-epair_handle_unit(struct if_clone *ifc, char *name, size_t len, int *punit)
+epair_clone_create(struct if_clone *ifc, char *name, size_t len,
+ struct ifc_data *ifd, struct ifnet **ifpp)
{
- int error = 0, unit, wildcard;
+ struct epair_softc *sca, *scb;
+ struct ifnet *ifp;
char *dp;
+ int error, unit, wildcard;
+ uint8_t eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */
/* Try to see if a special unit was requested. */
error = ifc_name2unit(name, &unit);
@@ -649,55 +633,29 @@
*/
for (dp = name; *dp != '\0'; dp++);
if (wildcard) {
- int slen = snprintf(dp, len - (dp - name), "%d", unit);
- if (slen > len - (dp - name) - 1) {
+ error = snprintf(dp, len - (dp - name), "%d", unit);
+ if (error > len - (dp - name) - 1) {
/* ifName too long. */
- error = ENOSPC;
- goto done;
+ ifc_free_unit(ifc, unit);
+ return (ENOSPC);
}
- dp += slen;
+ dp += error;
}
if (len - (dp - name) - 1 < 1) {
/* No space left for our [ab] suffix. */
- error = ENOSPC;
- goto done;
+ ifc_free_unit(ifc, unit);
+ return (ENOSPC);
}
*dp = 'b';
/* Must not change dp so we can replace 'a' by 'b' later. */
*(dp+1) = '\0';
/* Check if 'a' and 'b' interfaces already exist. */
- if (ifunit(name) != NULL) {
- error = EEXIST;
- goto done;
- }
-
+ if (ifunit(name) != NULL)
+ return (EEXIST);
*dp = 'a';
- if (ifunit(name) != NULL) {
- error = EEXIST;
- goto done;
- }
- *punit = unit;
-done:
- if (error != 0)
- ifc_free_unit(ifc, unit);
-
- return (error);
-}
-
-static int
-epair_clone_create(struct if_clone *ifc, char *name, size_t len,
- struct ifc_data *ifd, struct ifnet **ifpp)
-{
- struct epair_softc *sca, *scb;
- struct ifnet *ifp;
- char *dp;
- int error, unit;
- uint8_t eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */
-
- error = epair_handle_unit(ifc, name, len, &unit);
- if (error != 0)
- return (error);
+ if (ifunit(name) != NULL)
+ return (EEXIST);
/* Allocate memory for both [ab] interfaces */
sca = epair_alloc_sc(ifc);
@@ -723,7 +681,6 @@
ether_ifattach(ifp, eaddr);
/* Swap the name and finish initialization of interface <n>b. */
- dp = name + strlen(name) - 1;
*dp = 'b';
epair_setup_ifp(scb, name, unit);
@@ -743,8 +700,10 @@
strlcpy(name, sca->ifp->if_xname, len);
/* Tell the world, that we are ready to rock. */
- epair_set_state(sca->ifp, true);
- epair_set_state(scb->ifp, true);
+ sca->ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ if_link_state_change(sca->ifp, LINK_STATE_UP);
+ scb->ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ if_link_state_change(scb->ifp, LINK_STATE_UP);
*ifpp = sca->ifp;
@@ -791,8 +750,10 @@
scb = oifp->if_softc;
/* Frist get the interfaces down and detached. */
- epair_set_state(ifp, false);
- epair_set_state(oifp, false);
+ if_link_state_change(ifp, LINK_STATE_DOWN);
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ if_link_state_change(oifp, LINK_STATE_DOWN);
+ oifp->if_drv_flags &= ~IFF_DRV_RUNNING;
ether_ifdetach(ifp);
ether_ifdetach(oifp);
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -252,15 +252,15 @@
struct in6_ifaddr *ia = NULL;
struct in6_aliasreq *ifra = (struct in6_aliasreq *)data;
struct sockaddr_in6 *sa6;
+ int carp_attached = 0;
int error;
+ u_long ocmd = cmd;
/*
* Compat to make pre-10.x ifconfig(8) operable.
*/
- if (cmd == OSIOCAIFADDR_IN6) {
+ if (cmd == OSIOCAIFADDR_IN6)
cmd = SIOCAIFADDR_IN6;
- ifra->ifra_vhid = 0;
- }
switch (cmd) {
case SIOCGETSGCNT_IN6:
@@ -560,9 +560,142 @@
break;
case SIOCAIFADDR_IN6:
- error = in6_addifaddr(ifp, ifra, ia);
- ia = NULL;
+ {
+ struct nd_prefixctl pr0;
+ struct nd_prefix *pr;
+
+ /*
+ * first, make or update the interface address structure,
+ * and link it to the list.
+ */
+ if ((error = in6_update_ifa(ifp, ifra, ia, 0)) != 0)
+ goto out;
+ if (ia != NULL) {
+ if (ia->ia_ifa.ifa_carp)
+ (*carp_detach_p)(&ia->ia_ifa, true);
+ ifa_free(&ia->ia_ifa);
+ }
+ if ((ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr))
+ == NULL) {
+ /*
+ * this can happen when the user specify the 0 valid
+ * lifetime.
+ */
+ break;
+ }
+
+ if (cmd == ocmd && ifra->ifra_vhid > 0) {
+ if (carp_attach_p != NULL)
+ error = (*carp_attach_p)(&ia->ia_ifa,
+ ifra->ifra_vhid);
+ else
+ error = EPROTONOSUPPORT;
+ if (error)
+ goto out;
+ else
+ carp_attached = 1;
+ }
+
+ /*
+ * then, make the prefix on-link on the interface.
+ * XXX: we'd rather create the prefix before the address, but
+ * we need at least one address to install the corresponding
+ * interface route, so we configure the address first.
+ */
+
+ /*
+ * convert mask to prefix length (prefixmask has already
+ * been validated in in6_update_ifa().
+ */
+ bzero(&pr0, sizeof(pr0));
+ pr0.ndpr_ifp = ifp;
+ pr0.ndpr_plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
+ NULL);
+ if (pr0.ndpr_plen == 128) {
+ /* we don't need to install a host route. */
+ goto aifaddr_out;
+ }
+ pr0.ndpr_prefix = ifra->ifra_addr;
+ /* apply the mask for safety. */
+ IN6_MASK_ADDR(&pr0.ndpr_prefix.sin6_addr,
+ &ifra->ifra_prefixmask.sin6_addr);
+
+ /*
+ * XXX: since we don't have an API to set prefix (not address)
+ * lifetimes, we just use the same lifetimes as addresses.
+ * The (temporarily) installed lifetimes can be overridden by
+ * later advertised RAs (when accept_rtadv is non 0), which is
+ * an intended behavior.
+ */
+ pr0.ndpr_raf_onlink = 1; /* should be configurable? */
+ pr0.ndpr_raf_auto =
+ ((ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0);
+ pr0.ndpr_vltime = ifra->ifra_lifetime.ia6t_vltime;
+ pr0.ndpr_pltime = ifra->ifra_lifetime.ia6t_pltime;
+
+ /* add the prefix if not yet. */
+ if ((pr = nd6_prefix_lookup(&pr0)) == NULL) {
+ /*
+ * nd6_prelist_add will install the corresponding
+ * interface route.
+ */
+ if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0) {
+ if (carp_attached)
+ (*carp_detach_p)(&ia->ia_ifa, false);
+ goto out;
+ }
+ }
+
+ /* relate the address to the prefix */
+ if (ia->ia6_ndpr == NULL) {
+ ia->ia6_ndpr = pr;
+ pr->ndpr_addrcnt++;
+
+ /*
+ * If this is the first autoconf address from the
+ * prefix, create a temporary address as well
+ * (when required).
+ */
+ if ((ia->ia6_flags & IN6_IFF_AUTOCONF) &&
+ V_ip6_use_tempaddr && pr->ndpr_addrcnt == 1) {
+ int e;
+ if ((e = in6_tmpifadd(ia, 1, 0)) != 0) {
+ log(LOG_NOTICE, "in6_control: failed "
+ "to create a temporary address, "
+ "errno=%d\n", e);
+ }
+ }
+ }
+ nd6_prefix_rele(pr);
+
+ /*
+ * this might affect the status of autoconfigured addresses,
+ * that is, this address might make other addresses detached.
+ */
+ pfxlist_onlink_check();
+
+aifaddr_out:
+ /*
+ * Try to clear the flag when a new IPv6 address is added
+ * onto an IFDISABLED interface and it succeeds.
+ */
+ if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) {
+ struct in6_ndireq nd;
+
+ memset(&nd, 0, sizeof(nd));
+ nd.ndi.flags = ND_IFINFO(ifp)->flags;
+ nd.ndi.flags &= ~ND6_IFF_IFDISABLED;
+ if (nd6_ioctl(SIOCSIFINFO_FLAGS, (caddr_t)&nd, ifp) < 0)
+ log(LOG_NOTICE, "SIOCAIFADDR_IN6: "
+ "SIOCSIFINFO_FLAGS for -ifdisabled "
+ "failed.");
+ /*
+ * Ignore failure of clearing the flag intentionally.
+ * The failure means address duplication was detected.
+ */
+ }
break;
+ }
case SIOCDIFADDR_IN6:
in6_purgeifaddr(ia);
@@ -1191,151 +1324,6 @@
return (false);
}
-int
-in6_addifaddr(struct ifnet *ifp, struct in6_aliasreq *ifra, struct in6_ifaddr *ia)
-{
- struct nd_prefixctl pr0;
- struct nd_prefix *pr;
- int carp_attached = 0;
- int error;
-
- /*
- * first, make or update the interface address structure,
- * and link it to the list.
- */
- if ((error = in6_update_ifa(ifp, ifra, ia, 0)) != 0)
- goto out;
- if (ia != NULL) {
- if (ia->ia_ifa.ifa_carp)
- (*carp_detach_p)(&ia->ia_ifa, true);
- ifa_free(&ia->ia_ifa);
- }
- if ((ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr)) == NULL) {
- /*
- * this can happen when the user specify the 0 valid
- * lifetime.
- */
- return (0);
- }
-
- if (ifra->ifra_vhid > 0) {
- if (carp_attach_p != NULL)
- error = (*carp_attach_p)(&ia->ia_ifa,
- ifra->ifra_vhid);
- else
- error = EPROTONOSUPPORT;
- if (error)
- goto out;
- else
- carp_attached = 1;
- }
-
- /*
- * then, make the prefix on-link on the interface.
- * XXX: we'd rather create the prefix before the address, but
- * we need at least one address to install the corresponding
- * interface route, so we configure the address first.
- */
-
- /*
- * convert mask to prefix length (prefixmask has already
- * been validated in in6_update_ifa().
- */
- bzero(&pr0, sizeof(pr0));
- pr0.ndpr_ifp = ifp;
- pr0.ndpr_plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
- NULL);
- if (pr0.ndpr_plen == 128) {
- /* we don't need to install a host route. */
- goto aifaddr_out;
- }
- pr0.ndpr_prefix = ifra->ifra_addr;
- /* apply the mask for safety. */
- IN6_MASK_ADDR(&pr0.ndpr_prefix.sin6_addr,
- &ifra->ifra_prefixmask.sin6_addr);
-
- /*
- * XXX: since we don't have an API to set prefix (not address)
- * lifetimes, we just use the same lifetimes as addresses.
- * The (temporarily) installed lifetimes can be overridden by
- * later advertised RAs (when accept_rtadv is non 0), which is
- * an intended behavior.
- */
- pr0.ndpr_raf_onlink = 1; /* should be configurable? */
- pr0.ndpr_raf_auto =
- ((ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0);
- pr0.ndpr_vltime = ifra->ifra_lifetime.ia6t_vltime;
- pr0.ndpr_pltime = ifra->ifra_lifetime.ia6t_pltime;
-
- /* add the prefix if not yet. */
- if ((pr = nd6_prefix_lookup(&pr0)) == NULL) {
- /*
- * nd6_prelist_add will install the corresponding
- * interface route.
- */
- if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0) {
- if (carp_attached)
- (*carp_detach_p)(&ia->ia_ifa, false);
- goto out;
- }
- }
-
- /* relate the address to the prefix */
- if (ia->ia6_ndpr == NULL) {
- ia->ia6_ndpr = pr;
- pr->ndpr_addrcnt++;
-
- /*
- * If this is the first autoconf address from the
- * prefix, create a temporary address as well
- * (when required).
- */
- if ((ia->ia6_flags & IN6_IFF_AUTOCONF) &&
- V_ip6_use_tempaddr && pr->ndpr_addrcnt == 1) {
- int e;
- if ((e = in6_tmpifadd(ia, 1, 0)) != 0) {
- log(LOG_NOTICE, "in6_control: failed "
- "to create a temporary address, "
- "errno=%d\n", e);
- }
- }
- }
- nd6_prefix_rele(pr);
-
- /*
- * this might affect the status of autoconfigured addresses,
- * that is, this address might make other addresses detached.
- */
- pfxlist_onlink_check();
-
-aifaddr_out:
- /*
- * Try to clear the flag when a new IPv6 address is added
- * onto an IFDISABLED interface and it succeeds.
- */
- if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) {
- struct in6_ndireq nd;
-
- memset(&nd, 0, sizeof(nd));
- nd.ndi.flags = ND_IFINFO(ifp)->flags;
- nd.ndi.flags &= ~ND6_IFF_IFDISABLED;
- if (nd6_ioctl(SIOCSIFINFO_FLAGS, (caddr_t)&nd, ifp) < 0)
- log(LOG_NOTICE, "SIOCAIFADDR_IN6: "
- "SIOCSIFINFO_FLAGS for -ifdisabled "
- "failed.");
- /*
- * Ignore failure of clearing the flag intentionally.
- * The failure means address duplication was detected.
- */
- }
- error = 0;
-
-out:
- if (ia != NULL)
- ifa_free(&ia->ia_ifa);
- return (error);
-}
-
void
in6_purgeaddr(struct ifaddr *ifa)
{
diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h
--- a/sys/netinet6/in6_var.h
+++ b/sys/netinet6/in6_var.h
@@ -889,7 +889,6 @@
struct in6_ifaddr *, int);
void in6_prepare_ifra(struct in6_aliasreq *, const struct in6_addr *,
const struct in6_addr *);
-int in6_addifaddr(struct ifnet *, struct in6_aliasreq *, struct in6_ifaddr *);
void in6_purgeaddr(struct ifaddr *);
void in6_purgeifaddr(struct in6_ifaddr *);
int in6if_do_dad(struct ifnet *);
diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c
--- a/sys/netpfil/pf/pf_nv.c
+++ b/sys/netpfil/pf/pf_nv.c
@@ -1067,7 +1067,6 @@
return (NULL);
}
nvlist_add_nvlist(nvl, "src", addr);
- nvlist_destroy(addr);
addr = pf_keth_rule_addr_to_nveth_rule_addr(&krule->dst);
if (addr == NULL) {
@@ -1075,7 +1074,6 @@
return (NULL);
}
nvlist_add_nvlist(nvl, "dst", addr);
- nvlist_destroy(addr);
addr = pf_rule_addr_to_nvrule_addr(&krule->ipsrc);
if (addr == NULL) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 28, 11:03 AM (13 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26281913
Default Alt Text
D36745.id111075.diff (29 KB)
Attached To
Mode
D36745: stty(1): provide details about interaction with job control
Attached
Detach File
Event Timeline
Log In to Comment