Re: Reuse VM ids.
On Fri, 16 Nov 2018 16:15:14 +0100, Reyk Floeter wrote: > On Sat, Oct 27, 2018 at 02:53:16PM -0700, Ori Bernstein wrote: > > On Fri, 26 Oct 2018 01:57:15 +0200, Reyk Floeter wrote: > > > > > On Tue, Oct 23, 2018 at 10:21:08PM -0700, Ori Bernstein wrote: > > > > On Mon, 8 Oct 2018 07:59:15 -0700, Bob Beck wrote: > > > > > > > > > works here and I like it. but probably for after unlock > > > > > > > > > > > > > It's after unlock -- pinging for OKs. > > > > > > > > > > Not yet. Please include the VM's uid in the claim, e.g. > > > > > > claim_vmid(const char *name, uid_t uid) > > > > > > It is not a strong protection, but it doesn't make sense that other > > > users can run a VM with the same name and get the claimed Id. > > > > > > Reyk > > > > > > > Updated. > > > > Ok? > > > > Sorry for the delay... > > Two minor things: > > - I think config_purge() should clear env->vmd_known as it does with > vmd_vms and vmd_switches. > > - The use of static functions (static uint32_t vm_claimid) is disputable > but somewhat uncommon in OpenBSD. But even static functions do need a > prototype ("All functions are prototyped somewhere." - style(9)). Done. Anyone want to give a second ok? diff --git usr.sbin/vmd/config.c usr.sbin/vmd/config.c index 20a16f85442..c662d329eb4 100644 --- usr.sbin/vmd/config.c +++ usr.sbin/vmd/config.c @@ -87,7 +87,10 @@ config_init(struct vmd *env) if (what & CONFIG_VMS) { if ((env->vmd_vms = calloc(1, sizeof(*env->vmd_vms))) == NULL) return (-1); + if ((env->vmd_known = calloc(1, sizeof(*env->vmd_known))) == NULL) + return (-1); TAILQ_INIT(env->vmd_vms); + TAILQ_INIT(env->vmd_known); } if (what & CONFIG_SWITCHES) { if ((env->vmd_switches = calloc(1, @@ -109,6 +112,7 @@ void config_purge(struct vmd *env, unsigned int reset) { struct privsep *ps = &env->vmd_ps; + struct name2id *n2i; struct vmd_vm *vm; struct vmd_switch *vsw; unsigned int what; @@ -125,6 +129,10 @@ config_purge(struct vmd *env, unsigned int reset) while ((vm = TAILQ_FIRST(env->vmd_vms)) != NULL) { vm_remove(vm, __func__); } + while ((n2i = TAILQ_FIRST(env->vmd_known)) != NULL) { + TAILQ_REMOVE(env->vmd_known, n2i, entry); + free(n2i); + } env->vmd_nvm = 0; } if (what & CONFIG_SWITCHES && env->vmd_switches != NULL) { diff --git usr.sbin/vmd/vmd.c usr.sbin/vmd/vmd.c index 9423081df1e..5bb751511d0 100644 --- usr.sbin/vmd/vmd.c +++ usr.sbin/vmd/vmd.c @@ -62,6 +62,7 @@ intvmd_check_vmh(struct vm_dump_header *); int vm_instance(struct privsep *, struct vmd_vm **, struct vmop_create_params *, uid_t); int vm_checkinsflag(struct vmop_create_params *, unsigned int, uid_t); +uint32_t vm_claimid(const char *, int); struct vmd *env; @@ -1169,6 +1170,28 @@ vm_remove(struct vmd_vm *vm, const char *caller) free(vm); } +uint32_t +vm_claimid(const char *name, int uid) +{ + struct name2id *n2i = NULL; + + TAILQ_FOREACH(n2i, env->vmd_known, entry) + if (strcmp(n2i->name, name) == 0 && n2i->uid == uid) + return n2i->id; + + if (++env->vmd_nvm == 0) + fatalx("too many vms"); + if ((n2i = calloc(1, sizeof(struct name2id))) == NULL) + fatalx("could not alloc vm name"); + n2i->id = env->vmd_nvm; + n2i->uid = uid; + if (strlcpy(n2i->name, name, sizeof(n2i->name)) >= sizeof(n2i->name)) + fatalx("overlong vm name"); + TAILQ_INSERT_TAIL(env->vmd_known, n2i, entry); + + return n2i->id; +} + int vm_register(struct privsep *ps, struct vmop_create_params *vmc, struct vmd_vm **ret_vm, uint32_t id, uid_t uid) @@ -1300,11 +1323,8 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc, vm->vm_cdrom = -1; vm->vm_iev.ibuf.fd = -1; - if (++env->vmd_nvm == 0) - fatalx("too many vms"); - /* Assign a new internal Id if not specified */ - vm->vm_vmid = id == 0 ? env->vmd_nvm : id; + vm->vm_vmid = (id == 0) ? vm_claimid(vcp->vcp_name, uid) : id; log_debug("%s: registering vm %d", __func__, vm->vm_vmid); TAILQ_INSERT_TAIL(env->vmd_vms, vm, vm_entry); diff --git usr.sbin/vmd/vmd.h usr.sbin/vmd/vmd.h index de87e4337ee..6000dd6d63f 100644 --- usr.sbin/vmd/vmd.h +++ usr.sbin/vmd/vmd.h @@ -290,6 +290,14 @@ struct vmd_user { }; TAILQ_HEAD(userlist, vmd_user); +struct name2id { + charname[VMM_MAX_NAME_LEN]; + int uid; + int32_t id; + TAILQ_ENTRY(name2id)entry; +}; +TAILQ_HEAD(name2idlist, name2id); + struct addres
Re: pass prefixlen to rtable_mpath_reprio instead of mask
ok benno@ Claudio Jeker(cje...@diehard.n-r-g.com) on 2018.11.23 10:48:19 +0100: > This changes rtable_mpath_reprio() to take the prefixlen as argument > instead of the mask. ART is using the prefixlen internally and since we > switched to ART some time ago it no longer makes sense to convert the > prefixlen into a mask and back again. > > OK? > -- > :wq Claudio > > Index: net/route.c > === > RCS file: /cvs/src/sys/net/route.c,v > retrieving revision 1.378 > diff -u -p -r1.378 route.c > --- net/route.c 27 Sep 2018 12:36:57 - 1.378 > +++ net/route.c 23 Nov 2018 09:44:34 - > @@ -1626,8 +1626,8 @@ rt_if_linkstate_change(struct rtentry *r > > /* bring route up */ > rt->rt_flags |= RTF_UP; > - error = rtable_mpath_reprio(id, rt_key(rt), > - rt_plen2mask(rt, &sa_mask), rt->rt_priority & RTP_MASK, rt); > + error = rtable_mpath_reprio(id, rt_key(rt), rt_plen(rt), > + rt->rt_priority & RTP_MASK, rt); > } else { > /* >* Remove redirected and cloned routes (mainly ARP) > @@ -1646,8 +1646,8 @@ rt_if_linkstate_change(struct rtentry *r > > /* take route down */ > rt->rt_flags &= ~RTF_UP; > - error = rtable_mpath_reprio(id, rt_key(rt), > - rt_plen2mask(rt, &sa_mask), rt->rt_priority | RTP_DOWN, rt); > + error = rtable_mpath_reprio(id, rt_key(rt), rt_plen(rt), > + rt->rt_priority | RTP_DOWN, rt); > } > if_group_routechange(rt_key(rt), rt_plen2mask(rt, &sa_mask)); > > Index: net/rtable.c > === > RCS file: /cvs/src/sys/net/rtable.c,v > retrieving revision 1.66 > diff -u -p -r1.66 rtable.c > --- net/rtable.c 20 Nov 2018 10:28:08 - 1.66 > +++ net/rtable.c 23 Nov 2018 09:43:16 - > @@ -731,13 +731,12 @@ rtable_mpath_capable(unsigned int rtable > > int > rtable_mpath_reprio(unsigned int rtableid, struct sockaddr *dst, > -struct sockaddr *mask, uint8_t prio, struct rtentry *rt) > +int plen, uint8_t prio, struct rtentry *rt) > { > struct art_root *ar; > struct art_node *an; > struct srp_ref sr; > uint8_t *addr; > - int plen; > int error = 0; > > ar = rtable_get(rtableid, dst->sa_family); > @@ -745,9 +744,6 @@ rtable_mpath_reprio(unsigned int rtablei > return (EAFNOSUPPORT); > > addr = satoaddr(ar, dst); > - plen = rtable_satoplen(dst->sa_family, mask); > - if (plen == -1) > - return (EINVAL); > > rw_enter_write(&ar->ar_lock); > an = art_lookup(ar, addr, plen, &sr); > Index: net/rtable.h > === > RCS file: /cvs/src/sys/net/rtable.h,v > retrieving revision 1.21 > diff -u -p -r1.21 rtable.h > --- net/rtable.h 9 Sep 2018 10:07:38 - 1.21 > +++ net/rtable.h 23 Nov 2018 09:43:38 - > @@ -70,6 +70,6 @@ int rtable_walk(unsigned int, sa_famil > int rtable_mpath_capable(unsigned int, sa_family_t); > struct rtentry *rtable_mpath_match(unsigned int, struct rtentry *, >struct sockaddr *, uint8_t); > -int rtable_mpath_reprio(unsigned int, struct sockaddr *, > - struct sockaddr *, uint8_t, struct rtentry *); > +int rtable_mpath_reprio(unsigned int, struct sockaddr *, int, > + uint8_t, struct rtentry *); > #endif /* _NET_RTABLE_H_ */ >
Re: relayd and TLS client cert verification
Ashe Connor(a...@kivikakk.ee) on 2018.11.23 05:55:55 +: > Hi all, > > It appears that relayd doesn't support TLS client certificate validation > (in the manner that httpd does with "tls client ca [cafile]"). Would > there be interest in a patch that added such support? yes, a patch to support client certificates would be welcome. /Benno > > Apologies if I've missed something obvious here. > > Best, > > Ashe >
bgpd refactor aspath_match a bit
For origin validation I chacked the source_as in struct rde_aspath this is not really the right place. It should be in struct aspath since that holds all the ASPATH related stuff. Change this, move aspath_match out of util.c back into rde_attr.c and adjust code to use the cached value also in match from any source-as XYZ rules. This last bit causes a minor behavioural change since the old code extracted the last non AS_SET asnumber. The new code follows the ROA RFC and returns the rightmost AS for AS_SEQUENCE, the local AS for empty paths and AS_NONE (which is 0) for everything else. So now 'match from any source-as 0' will return all paths that do not have a final AS_SEQUENCE segment. The reason for this change is that I don't want to have two different behaviours for what we call source-as (the one in roa-set and the one on a filter). Diff includes bgpctl change and is based from /usr/src -- :wq Claudio Index: usr.sbin/bgpctl/bgpctl.c === RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v retrieving revision 1.223 diff -u -p -r1.223 bgpctl.c --- usr.sbin/bgpctl/bgpctl.c1 Nov 2018 10:09:52 - 1.223 +++ usr.sbin/bgpctl/bgpctl.c23 Nov 2018 14:41:53 - @@ -97,6 +97,7 @@ void mrt_to_bgpd_addr(union mrt_addr * const char *msg_type(u_int8_t); voidnetwork_bulk(struct parse_result *); const char *print_auth_method(enum auth_method); +int match_aspath(void *, u_int16_t, struct filter_as *); struct imsgbuf *ibuf; struct mrt_parser show_mrt = { show_mrt_dump, show_mrt_state, show_mrt_msg }; @@ -2080,8 +2081,7 @@ show_mrt_dump(struct mrt_rib *mr, struct } /* filter by AS */ if (req->as.type != AS_UNDEF && - !aspath_match(mre->aspath, mre->aspath_len, - &req->as, 0)) + !match_aspath(mre->aspath, mre->aspath_len, &req->as)) continue; if (req->flags & F_CTL_DETAIL) { @@ -2146,8 +2146,7 @@ network_mrt_dump(struct mrt_rib *mr, str } /* filter by AS */ if (req->as.type != AS_UNDEF && - !aspath_match(mre->aspath, mre->aspath_len, - &req->as, 0)) + !match_aspath(mre->aspath, mre->aspath_len, &req->as)) continue; bzero(&net, sizeof(net)); @@ -2685,7 +2684,67 @@ msg_type(u_int8_t type) } int -as_set_match(const struct as_set *a, u_int32_t asnum) +match_aspath(void *data, u_int16_t len, struct filter_as *f) { + u_int8_t*seg; + int final; + u_int16_tseg_size; + u_int8_t i, seg_len; + u_int32_tas = 0; + + if (f->type == AS_EMPTY) { + if (len == 0) + return (1); + else + return (0); + } + + seg = data; + + /* just check the leftmost AS */ + if (f->type == AS_PEER && len >= 6) { + as = aspath_extract(seg, 0); + if (f->as_min == as) + return (1); + else + return (0); + } + + for (; len >= 6; len -= seg_size, seg += seg_size) { + seg_len = seg[1]; + seg_size = 2 + sizeof(u_int32_t) * seg_len; + + final = (len == seg_size); + + if (f->type == AS_SOURCE) { + /* +* Just extract the rightmost AS +* but if that segment is an AS_SET then the rightmost +* AS of a previous AS_SEQUENCE segment should be used. +* Because of that just look at AS_SEQUENCE segments. +*/ + if (seg[0] == AS_SEQUENCE) + as = aspath_extract(seg, seg_len - 1); + /* not yet in the final segment */ + if (!final) + continue; + if (f->as_min == as) + return (1); + else + return (0); + } + /* AS_TRANSIT or AS_ALL */ + for (i = 0; i < seg_len; i++) { + /* +* the source (rightmost) AS is excluded from +* AS_TRANSIT matches. +*/ + if (final && i == seg_len - 1 && f->type == AS_TRANSIT) + return (0); + as = aspath_extract(seg, i); + if (f->as_min == as) + return (1); + } + } return (0); } Index: usr.sbin/bgpd/bgpd.h === RCS file
Re: net80211: less frequent background scans
On Fri, Nov 23, 2018 at 01:34:54PM +0100, Stefan Sperling wrote: > Every time we settle for the same AP after a background scan, > a timeout value is increased to avoid repeated background scans > in situations where no better AP is available. > > The backoff currently increments in steps of half a second. > This causes very frequent background scans for a few minutes > after association to an AP with a weak signal. If my math is > correct, we reach a backoff interval of one minute only after > 120 background scans that found no new AP. > > We could easily double or triple this backoff. > With this diff, we back off by one more second each time we end > up settling for the same AP. We could probably backoff even more, > but I'd prefer to try a relatively small change, for now. Would it make sense to use an exponential backoff with a maximum? > Tested with an AP where iwn(4) reports -62dBm and triggers > background scans most of the time. > > ok? > > Index: ieee80211_input.c > === > RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v > retrieving revision 1.202 > diff -u -p -r1.202 ieee80211_input.c > --- ieee80211_input.c 7 Aug 2018 18:13:14 - 1.202 > +++ ieee80211_input.c 23 Nov 2018 11:36:42 - > @@ -276,7 +276,7 @@ ieee80211_input(struct ifnet *ifp, struc > (ic->ic_flags & IEEE80211_F_BGSCAN) == 0 && > (ic->ic_flags & IEEE80211_F_DESBSSID) == 0) > timeout_add_msec(&ic->ic_bgscan_timeout, > - 500 * (ic->ic_bgscan_fail + 1)); > + 500 * (2 * (ic->ic_bgscan_fail + 1))); Why not make this just 1000 * (ic->ic_bgscan_fail + 1)? > } > } > > > > -- :wq Claudio
net80211: less frequent background scans
Every time we settle for the same AP after a background scan, a timeout value is increased to avoid repeated background scans in situations where no better AP is available. The backoff currently increments in steps of half a second. This causes very frequent background scans for a few minutes after association to an AP with a weak signal. If my math is correct, we reach a backoff interval of one minute only after 120 background scans that found no new AP. We could easily double or triple this backoff. With this diff, we back off by one more second each time we end up settling for the same AP. We could probably backoff even more, but I'd prefer to try a relatively small change, for now. Tested with an AP where iwn(4) reports -62dBm and triggers background scans most of the time. ok? Index: ieee80211_input.c === RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v retrieving revision 1.202 diff -u -p -r1.202 ieee80211_input.c --- ieee80211_input.c 7 Aug 2018 18:13:14 - 1.202 +++ ieee80211_input.c 23 Nov 2018 11:36:42 - @@ -276,7 +276,7 @@ ieee80211_input(struct ifnet *ifp, struc (ic->ic_flags & IEEE80211_F_BGSCAN) == 0 && (ic->ic_flags & IEEE80211_F_DESBSSID) == 0) timeout_add_msec(&ic->ic_bgscan_timeout, - 500 * (ic->ic_bgscan_fail + 1)); + 500 * (2 * (ic->ic_bgscan_fail + 1))); } }
Re: [RFC PATCH] [vmm] Lightweight mechanism to kick virtio VQs
On Fri, Oct 19, 2018 at 08:32:52PM +0200, Sergio Lopez wrote: > Yes, I ran some random read and random write tests with fio. The Guest > is Linux, mainly because its virtio implementation is more mature. Next > week I'll try with OpenBSD. Here are the (long due) numbers with an OpenBSD 6.4 Guest. While on Linux all tests performed better with kickfd, this time randread gets a ~10% improvement, while randwrite numbers are ~5% worse. Please keep in mind that those are just the inital numbers. There's still a lot of optimizations that can be applied on both the vmd side (specially on writes, with things like request merging and asynchronous I/O) and the Guest drivers (OpenBSD performance is roughly half of Linux's, which indicates there's plenty of room for improvement). In any case, I'd like to know if you think this kickfd feature is something worth pursuing, or should I move to something else. Cheers, Sergio. | OpenBSD 6.4 + kickfd | - randread # fio --clocksource=clock_gettime --name=randread --rw=randread --bs=4k --filename=/dev/sd1c --size=1g --numjobs=1 --ioengine=sync --iodepth=1 --direct=0 --group_reporting randread: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=sync, iodepth=1 fio-3.12-17-g0fcbc0 Starting 1 thread Jobs: 1 (f=1): [r(1)][100.0%][r=24.5MiB/s][r=6278 IOPS][eta 00m:00s] randread: (groupid=0, jobs=1): err= 0: pid=24580: Fri Nov 23 09:59:54 2018 read: IOPS=6120, BW=23.9MiB/s (25.1MB/s)(1024MiB/42831msec) clat (usec): min=10, max=10126, avg=127.91, stdev=36.28 lat (usec): min=19, max=10134, avg=136.25, stdev=36.58 clat percentiles (usec): | 1.00th=[ 110], 5.00th=[ 112], 10.00th=[ 113], 20.00th=[ 119], | 30.00th=[ 121], 40.00th=[ 126], 50.00th=[ 129], 60.00th=[ 131], | 70.00th=[ 131], 80.00th=[ 133], 90.00th=[ 135], 95.00th=[ 145], | 99.00th=[ 190], 99.50th=[ 208], 99.90th=[ 255], 99.95th=[ 318], | 99.99th=[ 766] bw ( KiB/s): min= 2669, max=24660, per=61.01%, avg=14936.35, stdev=7445.54, samples=75 iops: min= 667, max= 6165, avg=3733.80, stdev=1861.45, samples=75 lat (usec) : 20=0.03%, 50=0.01%, 100=0.01%, 250=99.84%, 500=0.08% lat (usec) : 750=0.02%, 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01% cpu : usr=0.69%, sys=41.15%, ctx=261996, majf=1, minf=3 IO depths: 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit: 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=262144,0,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): READ: bw=23.9MiB/s (25.1MB/s), 23.9MiB/s-23.9MiB/s (25.1MB/s-25.1MB/s), io=1024MiB (1074MB), run=42831-42831msec # ./fio --clocksource=clock_gettime --name=randread --rw=randread --bs=4k --filename=/dev/sd1c --size=1g --numjobs=2 --ioengine=sync --iodepth=1 --direct=0 --group_reporting fio: this platform does not support process shared mutexes, forcing use of threads. Use the 'thread' option to get rid of this warning. randread: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=sync, iodepth=1 ... fio-3.12-17-g0fcbc0 Starting 2 threads Jobs: 1 (f=1): [r(1),_(1)][98.8%][r=23.2MiB/s][r=5947 IOPS][eta 00m:01s] randread: (groupid=0, jobs=2): err= 0: pid=1989935168: Fri Nov 23 10:03:27 2018 read: IOPS=6366, BW=24.9MiB/s (26.1MB/s)(2048MiB/82356msec) clat (usec): min=10, max=1104.9k, avg=187.28, stdev=4505.64 lat (usec): min=19, max=1104.9k, avg=221.12, stdev=5417.17 clat percentiles (usec): | 1.00th=[20], 5.00th=[ 110], 10.00th=[ 113], 20.00th=[ 118], | 30.00th=[ 119], 40.00th=[ 120], 50.00th=[ 121], 60.00th=[ 122], | 70.00th=[ 127], 80.00th=[ 133], 90.00th=[ 135], 95.00th=[ 135], | 99.00th=[ 184], 99.50th=[ 221], 99.90th=[ 537], 99.95th=[ 906], | 99.99th=[225444] bw ( KiB/s): min= 110, max=24515, per=18.61%, avg=4738.70, stdev=5790.82, samples=242 iops: min= 27, max= 6128, avg=1184.30, stdev=1447.69, samples=242 lat (usec) : 20=1.53%, 50=1.88%, 100=0.04%, 250=96.25%, 500=0.17% lat (usec) : 750=0.07%, 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 20=0.01%, 50=0.02%, 100=0.01% lat (msec) : 250=0.02%, 500=0.01%, 750=0.01% cpu : usr=0.32%, sys=25.10%, ctx=638508, majf=0, minf=4 IO depths: 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit: 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=524288,0,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): READ: bw=2
pass prefixlen to rtable_mpath_reprio instead of mask
This changes rtable_mpath_reprio() to take the prefixlen as argument instead of the mask. ART is using the prefixlen internally and since we switched to ART some time ago it no longer makes sense to convert the prefixlen into a mask and back again. OK? -- :wq Claudio Index: net/route.c === RCS file: /cvs/src/sys/net/route.c,v retrieving revision 1.378 diff -u -p -r1.378 route.c --- net/route.c 27 Sep 2018 12:36:57 - 1.378 +++ net/route.c 23 Nov 2018 09:44:34 - @@ -1626,8 +1626,8 @@ rt_if_linkstate_change(struct rtentry *r /* bring route up */ rt->rt_flags |= RTF_UP; - error = rtable_mpath_reprio(id, rt_key(rt), - rt_plen2mask(rt, &sa_mask), rt->rt_priority & RTP_MASK, rt); + error = rtable_mpath_reprio(id, rt_key(rt), rt_plen(rt), + rt->rt_priority & RTP_MASK, rt); } else { /* * Remove redirected and cloned routes (mainly ARP) @@ -1646,8 +1646,8 @@ rt_if_linkstate_change(struct rtentry *r /* take route down */ rt->rt_flags &= ~RTF_UP; - error = rtable_mpath_reprio(id, rt_key(rt), - rt_plen2mask(rt, &sa_mask), rt->rt_priority | RTP_DOWN, rt); + error = rtable_mpath_reprio(id, rt_key(rt), rt_plen(rt), + rt->rt_priority | RTP_DOWN, rt); } if_group_routechange(rt_key(rt), rt_plen2mask(rt, &sa_mask)); Index: net/rtable.c === RCS file: /cvs/src/sys/net/rtable.c,v retrieving revision 1.66 diff -u -p -r1.66 rtable.c --- net/rtable.c20 Nov 2018 10:28:08 - 1.66 +++ net/rtable.c23 Nov 2018 09:43:16 - @@ -731,13 +731,12 @@ rtable_mpath_capable(unsigned int rtable int rtable_mpath_reprio(unsigned int rtableid, struct sockaddr *dst, -struct sockaddr *mask, uint8_t prio, struct rtentry *rt) +int plen, uint8_t prio, struct rtentry *rt) { struct art_root *ar; struct art_node *an; struct srp_ref sr; uint8_t *addr; - int plen; int error = 0; ar = rtable_get(rtableid, dst->sa_family); @@ -745,9 +744,6 @@ rtable_mpath_reprio(unsigned int rtablei return (EAFNOSUPPORT); addr = satoaddr(ar, dst); - plen = rtable_satoplen(dst->sa_family, mask); - if (plen == -1) - return (EINVAL); rw_enter_write(&ar->ar_lock); an = art_lookup(ar, addr, plen, &sr); Index: net/rtable.h === RCS file: /cvs/src/sys/net/rtable.h,v retrieving revision 1.21 diff -u -p -r1.21 rtable.h --- net/rtable.h9 Sep 2018 10:07:38 - 1.21 +++ net/rtable.h23 Nov 2018 09:43:38 - @@ -70,6 +70,6 @@ intrtable_walk(unsigned int, sa_famil int rtable_mpath_capable(unsigned int, sa_family_t); struct rtentry *rtable_mpath_match(unsigned int, struct rtentry *, struct sockaddr *, uint8_t); -int rtable_mpath_reprio(unsigned int, struct sockaddr *, -struct sockaddr *, uint8_t, struct rtentry *); +int rtable_mpath_reprio(unsigned int, struct sockaddr *, int, +uint8_t, struct rtentry *); #endif /* _NET_RTABLE_H_ */