Re: ospf6d: configured "type p2p" is lost on RTM_IFINFO (interface flap)

Atanas Vladimirov <[email protected]> Wed, 22 Jul 2026 09:47:18 +0300
Newsgroups gmane.os.openbsd.bugs
Message-ID <[email protected]>
On 2026-07-22 08:13, Bjorn Ketelaars wrote:
> On Tue 21/07/2026 19:14, Atanas Vladimirov wrote:
>> > Synopsis:	ospf6d forgets configured "type p2p" when the interface
>> 		generates an RTM_IFINFO message (e.g. ifconfig down/up)
>> > Category:	user
>> > Environment:
>> 	System      : OpenBSD -current (8.0-beta)
>>         Details     : OpenBSD 8.0-beta (GENERIC.MP) #45: Sat Jul 18 
>> 11:29:43
>> MDT 2026
>> [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
>> 
>> 	Architecture: OpenBSD.amd64
>> 	Machine     : amd64
>> 
>> > Description:
>> 	An interface configured with "type p2p" in ospf6d.conf silently
>> 	reverts to network type BROADCAST as soon as any RTM_IFINFO
>> 	message arrives for that interface (for example after
>> 	"ifconfig <if> down" / "ifconfig <if> up", or any other flags
>> 	change). The daemon then starts DR election on the link. If the
>> 	remote router keeps running the link as point-to-point, both
>> 	sides can still reach neighbor state FULL, but SPF discards the
>> 	link because the router-LSAs describe it inconsistently
>> 	(p2p link on one side, transit network plus network-LSA on the
>> 	other), so no routes are computed across it.
>> 
>> 	This is particularly easy to hit with wg(4) interfaces, which
>> 	advertise IFF_BROADCAST|IFF_MULTICAST (sys/net/if_wg.c):
>> 
>> 		ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOARP;
>> 
>> 	Root cause: if_update() in usr.sbin/ospf6d/interface.c
>> 	unconditionally re-derives iface->type from the kernel interface
>> 	flags every time it is called:
>> 
>> 		/* set type */
>> 		if (flags & IFF_POINTOPOINT)
>> 			iface->type = IF_TYPE_POINTOPOINT;
>> 		if (flags & IFF_BROADCAST && flags & IFF_MULTICAST)
>> 			iface->type = IF_TYPE_BROADCAST;
>> 
>> 	At startup this is masked: ospf6d.c calls if_init() first and
>> 	parse_config() afterwards, so the "type p2p" override from
>> 	parse.y wins. But the configured value is not remembered
>> 	anywhere. When an RTM_IFINFO arrives, the dispatch chain
>> 	kroute.c:if_change() -> kif_update() -> if_update() resets the
>> 	type to BROADCAST in the parent process, and the IMSG_IFINFO
>> 	handlers in ospfe.c and rde.c call if_update() again on their
>> 	own copies, resetting it there too. From that point on the
>> 	interface runs as broadcast until the daemon is restarted and
>> 	the config is re-applied.
>> 
>> 	ospfd (IPv4) does not have this problem, which makes the
>> 	asymmetry very visible when both daemons run over the same
>> 	tunnel: ospfd keeps kernel interface state in a separate
>> 	struct kif, derives iface->type only once when the iface is
>> 	created from config (interface.c:if_new()), and its IMSG_IFINFO
>> 	handler only copies flags/linkstate/mtu, never the type.
>> 
>> > How-To-Repeat:
>> 	1. Configure an interface with "type p2p" in ospf6d.conf.
>> 	   A wg(4) interface makes the bug visible because its flags
>> 	   include IFF_BROADCAST|IFF_MULTICAST, but any interface whose
>> 	   flags would not derive to POINTOPOINT works.
>> 
>> 		area 0.0.0.0 {
>> 			interface wg0 { type p2p }
>> 		}
>> 
>> 	2. Start ospf6d and verify:
>> 		# ospf6ctl show interface wg0 | grep 'network type'
>> 		-> network type POINTOPOINT
>> 	3. Generate an RTM_IFINFO for the interface:
>> 		# ifconfig wg0 down; ifconfig wg0 up
>> 	4. Check again:
>> 		# ospf6ctl show interface wg0 | grep 'network type'
>> 		-> network type BROADCAST, DR election in progress.
>> 	5. rcctl restart ospf6d restores POINTOPOINT (until the next
>> 	   flap).
>> 
>> > Fix:
>> 	I don't know.
>> 
>> OpenBSD 8.0-beta (GENERIC.MP) #45: Sat Jul 18 11:29:43 MDT 2026
>>     
>> [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
>> real mem = 34154913792 (32572MB)
>> avail mem = 33093713920 (31560MB)
>> random: good seed from bootblocks
>> mpath0 at root
>> scsibus0 at mpath0: 256 targets
>> mainbus0 at root
>> bios0 at mainbus0: SMBIOS rev. 3.0 @ 0x7fb76000 (62 entries)
>> bios0: vendor American Megatrends Inc. version "3.6" date 04/25/2025
>> bios0: Supermicro Super Server
>> efi0 at bios0: UEFI 2.4
>> efi0: American Megatrends rev 0x5000b
>> acpi0 at bios0: ACPI 5.0
>> acpi0: sleep states S0 S4 S5
>> acpi0: tables DSDT FACP APIC FPDT FIDT SPMI SLIC MCFG HPET LPIT SSDT 
>> SSDT
>> SSDT DBGP DBG2 SSDT SSDT UEFI SSDT DMAR BGRT EINJ ERST BERT HEST
>> acpi0: wakeup devices PEG0(S4) PEGP(S4) PEG1(S4) PEGP(S4) PEG2(S4) 
>> PEGP(S4)
>> RP09(S4) PXSX(S4) RP10(S4) PXSX(S4) RP11(S4) PXSX(S4) RP12(S4) 
>> PXSX(S4)
>> RP13(S4) PXSX(S4) [...]
>> acpitimer0 at acpi0: 3579545 Hz, 24 bits
>> acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
>> cpu0 at mainbus0: apid 0 (boot processor)
>> cpu0: Intel(R) Xeon(R) CPU E3-1220 v6 @ 3.00GHz, 3000.00 MHz, 
>> 06-9e-09,
>> patch 000000fa
>> cpu0: cpuid 1 
>> edx=bfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE> 
>> ecx=77fafbff<SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND>
>> cpu0: cpuid 6 eax=27f7<SENSOR,ARAT,PTS> ecx=9<EFFFREQ>
>> cpu0: cpuid 7.0 
>> ebx=29c6fbf<FSGSBASE,TSC_ADJUST,SGX,BMI1,HLE,AVX2,SMEP,BMI2,ERMS,INVPCID,RTM,MPX,RDSEED,ADX,SMAP,CLFLUSHOPT,PT>
>> edx=bc002e00<SRBDS_CTRL,MD_CLEAR,TSXFA,IBRS,IBPB,STIBP,L1DF,SSBD>
>> cpu0: cpuid a vers=4, gp=8, gpwidth=48, ff=3, ffwidth=48
>> cpu0: cpuid d.1 eax=f<XSAVEOPT,XSAVEC,XGETBV1,XSAVES>
>> cpu0: cpuid 80000001 edx=2c100800<NXE,PAGE1GB,RDTSCP,LONG>
>> ecx=121<LAHF,ABM,3DNOWP>
>> cpu0: cpuid 80000007 edx=100<ITSC>
>> cpu0: msr 10a=a000c04<RSBA,MISC_PKG_CT,ENERGY_FILT,GDS_CTRL,RFDS_NO>
>> cpu0: MELTDOWN
>> cpu0: 32KB 64b/line 8-way D-cache, 32KB 64b/line 8-way I-cache, 256KB
>> 64b/line 4-way L2 cache, 8MB 64b/line 16-way L3 cache
>> cpu0: smt 0, core 0, package 0, type P
>> mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges
>> cpu0: apic clock running at 24MHz
>> cpu0: mwait min=64, max=64, C-substates=0.2.1.2.4.1, IBE
>> cpu1 at mainbus0: apid 2 (application processor)
>> cpu1: Intel(R) Xeon(R) CPU E3-1220 v6 @ 3.00GHz, 3000.00 MHz, 
>> 06-9e-09,
>> patch 000000fa
>> cpu1: smt 0, core 1, package 0, type P
>> cpu2 at mainbus0: apid 4 (application processor)
>> cpu2: Intel(R) Xeon(R) CPU E3-1220 v6 @ 3.00GHz, 3000.00 MHz, 
>> 06-9e-09,
>> patch 000000fa
>> cpu2: smt 0, core 2, package 0, type P
>> cpu3 at mainbus0: apid 6 (application processor)
>> cpu3: Intel(R) Xeon(R) CPU E3-1220 v6 @ 3.00GHz, 3000.00 MHz, 
>> 06-9e-09,
>> patch 000000fa
>> cpu3: smt 0, core 3, package 0, type P
>> ioapic0 at mainbus0: apid 2 pa 0xfec00000, version 20, 24 pins
>> acpimcfg0 at acpi0
>> acpimcfg0: addr 0xe0000000, bus 0-255
>> acpihpet0 at acpi0: 23999999 Hz
>> acpiprt0 at acpi0: bus 0 (PCI0)
>> acpiprt1 at acpi0: bus 1 (PEG0)
>> acpiprt2 at acpi0: bus 2 (PEG1)
>> acpiprt3 at acpi0: bus -1 (PEG2)
>> acpiprt4 at acpi0: bus 6 (RP09)
>> acpiprt5 at acpi0: bus 7 (RP10)
>> acpiprt6 at acpi0: bus 8 (RP11)
>> acpiprt7 at acpi0: bus 9 (BR51)
>> acpiprt8 at acpi0: bus -1 (RP12)
>> acpiprt9 at acpi0: bus -1 (RP13)
>> acpiprt10 at acpi0: bus -1 (RP01)
>> acpiprt11 at acpi0: bus -1 (RP05)
>> acpiprt12 at acpi0: bus -1 (RP17)
>> acpiprt13 at acpi0: bus -1 (RP18)
>> acpiprt14 at acpi0: bus -1 (RP19)
>> acpiprt15 at acpi0: bus -1 (RP20)
>> acpiprt16 at acpi0: bus -1 (RP14)
>> acpiprt17 at acpi0: bus -1 (RP15)
>> acpiprt18 at acpi0: bus -1 (RP16)
>> acpiec0 at acpi0: not present
>> acpipci0 at acpi0 PCI0: 0x00000000 0x00000011 0x00000001
>> com0 at acpi0 UAR1 addr 0x3f8/0x8 irq 4: ns16550a, 16 byte fifo
>> com1 at acpi0 UAR2 addr 0x2f8/0x8 irq 3: ns16550a, 16 byte fifo
>> com1: console
>> acpicmos0 at acpi0
>> "IPI0001" at acpi0 not configured
>> "INT0E0C" at acpi0 not configured
>> acpibtn0 at acpi0: SLPB
>> intelpmc0 at acpi0: PEPD
>> state 0: 0x7f:1:2:0x00:0x0000000000000060
>> counter: 0x7f:64:0:0x00:0x0000000000000632
>> frequency: 0
>> state 1: 0x7f:1:2:0x00:0x0000000000000060
>> counter: 0x7f:64:0:0x00:0x0000000000000632
>> frequency: 0
>> acpibtn1 at acpi0: PWRB
>> "PNP0C0B" at acpi0 not configured
>> "PNP0C0B" at acpi0 not configured
>> "PNP0C0B" at acpi0 not configured
>> "PNP0C0B" at acpi0 not configured
>> "PNP0C0B" at acpi0 not configured
>> acpicpu0 at acpi0: C3(200@256 mwait.1@0x40), C2(200@151 mwait.1@0x33),
>> C1(1000@1 mwait.1), PSS
>> acpicpu1 at acpi0: C3(200@256 mwait.1@0x40), C2(200@151 mwait.1@0x33),
>> C1(1000@1 mwait.1), PSS
>> acpicpu2 at acpi0: C3(200@256 mwait.1@0x40), C2(200@151 mwait.1@0x33),
>> C1(1000@1 mwait.1), PSS
>> acpicpu3 at acpi0: C3(200@256 mwait.1@0x40), C2(200@151 mwait.1@0x33),
>> C1(1000@1 mwait.1), PSS
>> acpipwrres0 at acpi0: PG00, resource for PEG0
>> acpipwrres1 at acpi0: PG01, resource for PEG1
>> acpipwrres2 at acpi0: PG02, resource for PEG2
>> acpipwrres3 at acpi0: WRST
>> acpipwrres4 at acpi0: WRST
>> acpipwrres5 at acpi0: WRST
>> acpipwrres6 at acpi0: WRST
>> acpipwrres7 at acpi0: WRST
>> acpipwrres8 at acpi0: WRST
>> acpipwrres9 at acpi0: WRST
>> acpipwrres10 at acpi0: WRST
>> acpipwrres11 at acpi0: WRST
>> acpipwrres12 at acpi0: WRST
>> acpipwrres13 at acpi0: WRST
>> acpipwrres14 at acpi0: WRST
>> acpipwrres15 at acpi0: WRST
>> acpipwrres16 at acpi0: WRST
>> acpipwrres17 at acpi0: WRST
>> acpipwrres18 at acpi0: WRST
>> acpipwrres19 at acpi0: WRST
>> acpipwrres20 at acpi0: WRST
>> acpipwrres21 at acpi0: WRST
>> acpipwrres22 at acpi0: WRST
>> acpipwrres23 at acpi0: FN00, resource for FAN0
>> acpipwrres24 at acpi0: FN01, resource for FAN1
>> acpipwrres25 at acpi0: FN02, resource for FAN2
>> acpipwrres26 at acpi0: FN03, resource for FAN3
>> acpipwrres27 at acpi0: FN04, resource for FAN4
>> acpitz0 at acpi0
>> acpitz0: critical temperature is 119 degC
>> acpitz1 at acpi0
>> acpitz1: critical temperature is 119 degC
>> acpivideo0 at acpi0: GFX0
>> acpivout0 at acpivideo0: DD1F
>> ipmi at mainbus0 not configured
>> cpu0: using VERW MDS workaround (except on vmm entry)
>> cpu0: Enhanced SpeedStep 3000 MHz: speeds: 3001, 3000, 2800, 2700, 
>> 2500,
>> 2400, 2200, 2100, 1900, 1700, 1600, 1400, 1300, 1100, 1000, 800 MHz
>> pci0 at mainbus0 bus 0
>> pchb0 at pci0 dev 0 function 0 "Intel Xeon E3-1200 v6/7 Host" rev 0x05
>> ppb0 at pci0 dev 1 function 0 "Intel Core 6G PCIE" rev 0x05: msi
>> pci1 at ppb0 bus 1
>> ix0 at pci1 dev 0 function 0 "Intel 82599" rev 0x01, msix, 4 queues, 
>> address
>> 90:e2:ba:f3:2e:1c
>> ix1 at pci1 dev 0 function 1 "Intel 82599" rev 0x01, msix, 4 queues, 
>> address
>> 90:e2:ba:f3:2e:1d
>> ppb1 at pci0 dev 1 function 1 "Intel Core 6G PCIE" rev 0x05: msi
>> pci2 at ppb1 bus 2
>> ppb2 at pci2 dev 0 function 0 "IDT 89HPES12N3A" rev 0x0e
>> pci3 at ppb2 bus 3
>> ppb3 at pci3 dev 2 function 0 "IDT 89HPES12N3A" rev 0x0e
>> pci4 at ppb3 bus 4
>> em0 at pci4 dev 0 function 0 "Intel 82571EB" rev 0x06: apic 2 int 16,
>> address 00:15:17:bc:a9:65
>> em1 at pci4 dev 0 function 1 "Intel 82571EB" rev 0x06: apic 2 int 19,
>> address 00:15:17:bc:a9:64
>> ppb4 at pci3 dev 4 function 0 "IDT 89HPES12N3A" rev 0x0e
>> pci5 at ppb4 bus 5
>> em2 at pci5 dev 0 function 0 "Intel 82571EB" rev 0x06: apic 2 int 18,
>> address 00:15:17:bc:a9:67
>> em3 at pci5 dev 0 function 1 "Intel 82571EB" rev 0x06: apic 2 int 17,
>> address 00:15:17:bc:a9:66
>> "Intel 100 Series ISH" rev 0x31 at pci0 dev 19 function 0 not 
>> configured
>> xhci0 at pci0 dev 20 function 0 "Intel 100 Series xHCI" rev 0x31: msi, 
>> xHCI
>> 1.0
>> usb0 at xhci0: USB revision 3.0
>> uhub0 at usb0 configuration 1 interface 0 "Intel xHCI root hub" rev
>> 3.00/1.00 addr 1
>> pchtemp0 at pci0 dev 20 function 2 "Intel 100 Series Thermal" rev 0x31
>> "Intel 100 Series MEI" rev 0x31 at pci0 dev 22 function 0 not 
>> configured
>> ahci0 at pci0 dev 23 function 0 "Intel 100 Series AHCI" rev 0x31: msi, 
>> AHCI
>> 1.3.1
>> ahci0: port 0: 6.0Gb/s
>> ahci0: port 1: 6.0Gb/s
>> scsibus1 at ahci0: 32 targets
>> sd0 at scsibus1 targ 0 lun 0: <ATA, SAMSUNG MZ7L33T8, JXTC>
>> naa.5002538f02212827
>> sd0: 3662830MB, 512 bytes/sector, 7501476528 sectors, thin
>> sd1 at scsibus1 targ 1 lun 0: <ATA, SAMSUNG MZ7LM3T8, GXT5>
>> naa.5002538c407c5ab3
>> sd1: 3662830MB, 512 bytes/sector, 7501476528 sectors, thin
>> ppb5 at pci0 dev 29 function 0 "Intel 100 Series PCIE" rev 0xf1: msi
>> pci6 at ppb5 bus 6
>> em4 at pci6 dev 0 function 0 "Intel I210" rev 0x03: msi, address
>> ac:1f:6b:96:83:30
>> ppb6 at pci0 dev 29 function 1 "Intel 100 Series PCIE" rev 0xf1: msi
>> pci7 at ppb6 bus 7
>> em5 at pci7 dev 0 function 0 "Intel I210" rev 0x03: msi, address
>> ac:1f:6b:96:83:31
>> ppb7 at pci0 dev 29 function 2 "Intel 100 Series PCIE" rev 0xf1: msi
>> pci8 at ppb7 bus 8
>> ppb8 at pci8 dev 0 function 0 "ASPEED Technology AST1150 PCI" rev 0x03
>> pci9 at ppb8 bus 9
>> "ASPEED Technology AST2000" rev 0x30 at pci9 dev 0 function 0 not 
>> configured
>> pcib0 at pci0 dev 31 function 0 "Intel C232 LPC" rev 0x31
>> "Intel 100 Series PMC" rev 0x31 at pci0 dev 31 function 2 not 
>> configured
>> ichiic0 at pci0 dev 31 function 4 "Intel 100 Series SMBus" rev 0x31: 
>> apic 2
>> int 16
>> iic0 at ichiic0
>> iic0: addr 0x19 00=00 01=00 02=04 03=00 04=06 05=02 06=1c 07=22 08=00 
>> words
>> 00=00ef 01=000d 02=04b0 03=0000 04=0610 05=026c 06=1c85 07=2221
>> iic0: addr 0x1b 00=00 01=00 02=04 03=00 04=06 05=02 06=1c 07=22 08=00 
>> words
>> 00=00ef 01=000d 02=04b0 03=0000 04=0610 05=0268 06=1c85 07=2221
>> spdmem0 at iic0 addr 0x51: 16GB DDR4 SDRAM ECC PC4-25600 with thermal 
>> sensor
>> spdmem1 at iic0 addr 0x53: 16GB DDR4 SDRAM ECC PC4-25600 with thermal 
>> sensor
>> isa0 at pcib0
>> isadma0 at isa0
>> pcppi0 at isa0 port 0x61
>> spkr0 at pcppi0
>> vmm0 at mainbus0: VMX/EPT
>> efifb0 at mainbus0: 1024x768, 32bpp
>> wsdisplay0 at efifb0 mux 1
>> wsdisplay0: screen 0-5 added (std, vt100 emulation)
>> enable mbufs in high memory
>> uplcom0 at uhub0 port 6 configuration 1 interface 0 "Prolific 
>> Technology
>> Inc. USB-Serial Controller" rev 1.10/3.00 addr 2
>> ucom0 at uplcom0: usb0.0.00006.0
>> uhidev0 at uhub0 port 8 configuration 1 interface 0 "Logitech USB 
>> Receiver"
>> rev 2.00/29.00 addr 3
>> uhidev0: iclass 3/1
>> ukbd0 at uhidev0: 8 variable keys, 6 key codes
>> wskbd0 at ukbd0 mux 1
>> wskbd0: connecting to wsdisplay0
>> uhidev1 at uhub0 port 8 configuration 1 interface 1 "Logitech USB 
>> Receiver"
>> rev 2.00/29.00 addr 3
>> uhidev1: iclass 3/1, 17 report ids
>> uhidpp0 at uhidev1 device 1 keyboard " ", device 2 mouse ""
>> ums0 at uhidev1 reportid 2: 16 buttons, Z and W dir
>> wsmouse0 at ums0 mux 0
>> ucc0 at uhidev1 reportid 3: 652 usages, 20 keys, array
>> wskbd1 at ucc0 mux 1
>> wskbd1: connecting to wsdisplay0
>> uhid0 at uhidev1 reportid 4: input=1, output=0, feature=0
>> uhub1 at uhub0 port 9 configuration 1 interface 0 "ATEN International
>> product 0x7000" rev 2.00/0.00 addr 4
>> uhidev2 at uhub1 port 1 configuration 1 interface 0 "ATEN 
>> International
>> product 0x2419" rev 1.10/1.00 addr 5
>> uhidev2: iclass 3/1
>> ukbd1 at uhidev2: 8 variable keys, 6 key codes
>> wskbd2 at ukbd1 mux 1
>> wskbd2: connecting to wsdisplay0
>> uhidev3 at uhub1 port 1 configuration 1 interface 1 "ATEN 
>> International
>> product 0x2419" rev 1.10/1.00 addr 5
>> uhidev3: iclass 3/1
>> ums1 at uhidev3: 3 buttons, Z dir
>> wsmouse1 at ums1 mux 0
>> vscsi0 at root
>> scsibus2 at vscsi0: 256 targets
>> softraid0 at root
>> scsibus3 at softraid0: 256 targets
>> sd2 at scsibus3 targ 1 lun 0: <OPENBSD, SR RAID 1, 006>
>> sd2: 953869MB, 512 bytes/sector, 1953524576 sectors
>> sd3 at scsibus3 targ 2 lun 0: <OPENBSD, SR RAID 1, 006>
>> sd3: 953869MB, 512 bytes/sector, 1953524576 sectors
>> sd4 at scsibus3 targ 3 lun 0: <OPENBSD, SR RAID 1, 006>
>> sd4: 915714MB, 512 bytes/sector, 1875383423 sectors
>> root on sd4a (22c9e9d08ea8ad79.a) swap on sd4b dump on sd4b
>> 
> 
> I could reproduce where an interface configured with type p2p in
> ospf6d.conf reverts back to BROADCAST after a link bounce.
> 
> When an interface receives a link update (RTM_IFINFO), if_update()
> unconditionally re-derives iface->type from interface flags
> (IFF_POINTOPOINT, IFF_BROADCAST), overwriting the explicit 
> configuration
> set during parsing.
> 
> Diff below introduces F_IFACE_TYPE in cflags to track when an interface
> type was set by configuration, and only auto-derive the type from
> interface flags when F_IFACE_TYPE is not set.
> 
> I am far from an expert here, so any feedback is appreciated.
> 

Thanks for your reply and for the patch.
I just tested it and can confirm that it works as it should :)

> 
> diff --git usr.sbin/ospf6d/interface.c usr.sbin/ospf6d/interface.c
> index b82989d132a..3056e87ac3d 100644
> --- usr.sbin/ospf6d/interface.c
> +++ usr.sbin/ospf6d/interface.c
> @@ -244,11 +244,13 @@ if_update(struct iface *iface, int mtu, int 
> flags, u_int8_t type,
>  	iface->baudrate = rate;
>  	iface->rdomain = rdomain;
> 
> -	/* set type */
> -	if (flags & IFF_POINTOPOINT)
> -		iface->type = IF_TYPE_POINTOPOINT;
> -	if (flags & IFF_BROADCAST && flags & IFF_MULTICAST)
> -		iface->type = IF_TYPE_BROADCAST;
> +	/* derive type from interface flags if not explicitly configured */
> +	if ((iface->cflags & F_IFACE_TYPE) == 0) {
> +		if (flags & IFF_POINTOPOINT)
> +			iface->type = IF_TYPE_POINTOPOINT;
> +		if (flags & IFF_BROADCAST && flags & IFF_MULTICAST)
> +			iface->type = IF_TYPE_BROADCAST;
> +	}
>  	if (flags & IFF_LOOPBACK) {
>  		iface->type = IF_TYPE_POINTOPOINT;
>  		iface->cflags |= F_IFACE_PASSIVE;
> diff --git usr.sbin/ospf6d/ospf6d.h usr.sbin/ospf6d/ospf6d.h
> index 5e2e1d35b4c..e3aca3c001e 100644
> --- usr.sbin/ospf6d/ospf6d.h
> +++ usr.sbin/ospf6d/ospf6d.h
> @@ -331,6 +331,7 @@ struct iface {
>  	u_int8_t		 cflags;
>  #define F_IFACE_PASSIVE		0x01
>  #define F_IFACE_CONFIGURED	0x02
> +#define F_IFACE_TYPE		0x04
>  };
> 
>  struct ifaddrchange {
> diff --git usr.sbin/ospf6d/parse.y usr.sbin/ospf6d/parse.y
> index b25e030124c..a20b7218a99 100644
> --- usr.sbin/ospf6d/parse.y
> +++ usr.sbin/ospf6d/parse.y
> @@ -554,8 +554,10 @@ interface	: INTERFACE STRING	{
>  			iface->metric = defs->metric;
>  			iface->priority = defs->priority;
>  			iface->cflags |= F_IFACE_CONFIGURED;
> -			if (defs->p2p == 1)
> +			if (defs->p2p == 1) {
>  				iface->type = IF_TYPE_POINTOPOINT;
> +				iface->cflags |= F_IFACE_TYPE;
> +			}
>  			iface = NULL;
>  			/* interface is always part of an area */
>  			defs = &areadefs;