Page MenuHomeFreeBSD

D36745.id111075.diff
No OneTemporary

D36745.id111075.diff

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

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)

Event Timeline