ksh garbage printing
The following patch fixes a bug in ksh I reported some time ago (http://marc.info/?l=openbsd-bugsm=137292039914229w=2). I committed this patch to Bitrig in December 2013; it seems to work fine so far. Here the bug report inline for reference. Description: When using a keybinding that starts with ^[ while in history search mode in ksh, history search is aborted and the rest of the keybinding is printed at the current cursor position. search-history is implemented in x_search_hist in bin/ksh/emacs.c. x_search_hist returns on the first ^[ character in the input stream, so the remaining characters of the escape sequence are interpreted by x_emacs. e.g.: pressing the left arrow key when in search mode inserts [D at the cursor position. How-To-Repeat: set -o emacs Type ^R. Use arrow key or home/end. Some garbage is printed at the cursor position. Fix: unknown FYI: bash assumes that ^[ is part of a longer keybinding when more characters arrive in a duration of 0.1 seconds, but that looks like an ugly solution to me. Anyone cares to commit (or comment)? cheers, natano --- Only consume ^[ in search mode when not part of an escape sequence Index: edit.c === RCS file: /cvs/src/bin/ksh/edit.c,v retrieving revision 1.39 diff -u -r1.39 edit.c --- edit.c 17 Dec 2013 16:37:05 - 1.39 +++ edit.c 3 Oct 2014 20:45:35 - @@ -17,6 +17,7 @@ #include ctype.h #include libgen.h #include sys/stat.h +#include poll.h static void x_sigwinch(int); @@ -145,6 +146,16 @@ { while (*s != 0) shf_putc(*s++, shl_out); +} + +int +x_avail(void) +{ + struct pollfd pfd[1]; + + pfd[0].fd = STDIN_FILENO; + pfd[0].events = POLLIN; + return poll(pfd, 1, 0) == 1; } bool Index: edit.h === RCS file: /cvs/src/bin/ksh/edit.h,v retrieving revision 1.9 diff -u -r1.9 edit.h --- edit.h 30 May 2011 17:14:35 - 1.9 +++ edit.h 3 Oct 2014 20:45:35 - @@ -48,6 +48,7 @@ void x_flush(void); void x_putc(int); void x_puts(const char *); +intx_avail(void); bool x_mode(bool); intpromptlen(const char *, const char **); intx_do_comment(char *, int, int *); Index: emacs.c === RCS file: /cvs/src/bin/ksh/emacs.c,v retrieving revision 1.48 diff -u -r1.48 emacs.c --- emacs.c 17 Dec 2013 16:37:05 - 1.48 +++ emacs.c 3 Oct 2014 20:45:35 - @@ -884,9 +884,12 @@ if ((c = x_e_getc()) 0) return KSTD; f = kb_find_hist_func(c); - if (c == CTRL('[')) + if (c == CTRL('[')) { + /* might be part of an escape sequence */ + if (x_avail()) + x_e_ungetc(c); break; - else if (f == x_search_hist) + } else if (f == x_search_hist) offset = x_search(pat, 0, offset); else if (f == x_del_back) { if (p == pat) {
ksh emacs mode cleanup
Below some code cleanup for ksh's emacs mode. cheers, natano --- Get rid of left over null elements in x_ftab as NELEM() is used instead. Index: emacs.c === RCS file: /cvs/src/bin/ksh/emacs.c,v retrieving revision 1.48 diff -u -r1.48 emacs.c --- emacs.c 17 Dec 2013 16:37:05 - 1.48 +++ emacs.c 4 Oct 2014 06:54:54 - @@ -254,13 +254,9 @@ { x_fold_upper, upcase-word, XF_ARG }, { x_set_arg,set-arg, XF_NOBIND }, { x_comment,comment, 0 }, - { 0, 0, 0 }, #ifdef DEBUG { x_debug_info, debug-info, 0 }, -#else - { 0, 0, 0 }, #endif - { 0, 0, 0 }, }; int @@ -1397,10 +1393,7 @@ if (list) { /* show all function names */ for (i = 0; i NELEM(x_ftab); i++) { - if (x_ftab[i].xf_name == NULL) - continue; - if (x_ftab[i].xf_name - !(x_ftab[i].xf_flags XF_NOBIND)) + if (!(x_ftab[i].xf_flags XF_NOBIND)) shprintf(%s\n, x_ftab[i].xf_name); } return (0); @@ -1449,8 +1442,6 @@ /* set non macro binding */ for (i = 0; i NELEM(x_ftab); i++) { - if (x_ftab[i].xf_name == NULL) - continue; if (!strcmp(x_ftab[i].xf_name, a2)) { /* delete old mapping */ TAILQ_FOREACH_SAFE(k, kblist, entry, kb) --- Simplify x_emacs_putbuf(). Index: emacs.c === RCS file: /cvs/src/bin/ksh/emacs.c,v retrieving revision 1.48 diff -u -r1.48 emacs.c --- emacs.c 17 Dec 2013 16:37:05 - 1.48 +++ emacs.c 4 Oct 2014 07:02:47 - @@ -466,11 +466,7 @@ static int x_emacs_putbuf(const char *s, size_t len) { - int rval; - - if ((rval = x_do_ins(s, len)) != 0) - return (rval); - return (rval); + return x_do_ins(s, len); } static int --- Improve kb_add to not loop over the arguments twice. Let kb_add check line boundaries; patch provided by Pedro Martelletto. Index: emacs.c === RCS file: /cvs/src/bin/ksh/emacs.c,v retrieving revision 1.48 diff -u -r1.48 emacs.c --- emacs.c 17 Dec 2013 16:37:05 - 1.48 +++ emacs.c 4 Oct 2014 07:04:25 - @@ -1351,19 +1351,18 @@ kb_add(void *func, void *args, ...) { va_list ap; - int i, count; charl[LINE + 1]; + int i; va_start(ap, args); - count = 0; - while (va_arg(ap, unsigned int) != 0) - count++; - va_end(ap); - - va_start(ap, args); - for (i = 0; i = count /* = is correct */; i++) + for (i = 0; i sizeof(l) - 1; i++) { l[i] = (unsigned char)va_arg(ap, unsigned int); + if (l[i] == (unsigned char)'\0') + break; + } va_end(ap); + + l[i] = (unsigned char)'\0'; return (kb_add_string(func, args, l)); } --- Let's relief emacs.c from it's identify crisis. Index: emacs.c === RCS file: /cvs/src/bin/ksh/emacs.c,v retrieving revision 1.48 diff -u -r1.48 emacs.c --- emacs.c 17 Dec 2013 16:37:05 - 1.48 +++ emacs.c 4 Oct 2014 06:56:13 - @@ -2160,4 +2160,4 @@ return (xlp); } -#endif /* EDIT */ +#endif /* EMACS */
Re: syslogd libevent
On Sat, Oct 04, 2014 at 01:29:21AM +0200, Alexander Bluhm wrote: Hi, After some preparation, I can convert syslogd to use libevent now. ok? bluhm Index: usr.sbin/syslogd/Makefile === RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/Makefile,v retrieving revision 1.5 diff -u -p -u -p -r1.5 Makefile --- usr.sbin/syslogd/Makefile 4 Jan 2004 08:28:49 - 1.5 +++ usr.sbin/syslogd/Makefile 3 Oct 2014 22:30:00 - @@ -1,7 +1,8 @@ #$OpenBSD: Makefile,v 1.5 2004/01/04 08:28:49 djm Exp $ -PROG=syslogd -SRCS=syslogd.c ttymsg.c privsep.c privsep_fdpass.c ringbuf.c -MAN= syslogd.8 syslog.conf.5 +PROG = syslogd +SRCS = syslogd.c ttymsg.c privsep.c privsep_fdpass.c ringbuf.c +MAN =syslogd.8 syslog.conf.5 +LDFLAGS =-levent This should be: LDADD= -levent DPADD= ${LIBEVENT} Rather than LDFLAGS. Otherwise this looks good and works fine for me. .include bsd.prog.mk Index: usr.sbin/syslogd/privsep.c === RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v retrieving revision 1.47 diff -u -p -u -p -r1.47 privsep.c --- usr.sbin/syslogd/privsep.c3 Oct 2014 21:55:22 - 1.47 +++ usr.sbin/syslogd/privsep.c3 Oct 2014 23:03:50 - @@ -171,21 +171,21 @@ priv_init(char *conf, int numeric, int l close(socks[1]); /* Close descriptors that only the unpriv child needs */ + if (fd_ctlconn != -1) + close(fd_ctlconn); + if (fd_ctlsock != -1) + close(fd_ctlsock); + if (fd_klog != -1) + close(fd_klog); + if (fd_sendsys != -1) + close(fd_sendsys); + if (fd_udp != -1) + close(fd_udp); + if (fd_udp6 != -1) + close(fd_udp6); for (i = 0; i nunix; i++) - if (pfd[PFD_UNIX_0 + i].fd != -1) - close(pfd[PFD_UNIX_0 + i].fd); - if (pfd[PFD_INET].fd != -1) - close(pfd[PFD_INET].fd); - if (pfd[PFD_INET6].fd != -1) - close(pfd[PFD_INET6].fd); - if (pfd[PFD_CTLSOCK].fd != -1) - close(pfd[PFD_CTLSOCK].fd); - if (pfd[PFD_CTLCONN].fd != -1) - close(pfd[PFD_CTLCONN].fd); - if (pfd[PFD_KLOG].fd != -1) - close(pfd[PFD_KLOG].fd); - if (pfd[PFD_SENDSYS].fd != -1) - close(pfd[PFD_SENDSYS].fd); + if (fd_unix[i] != -1) + close(fd_unix[i]); /* Save the config file specified by the child process */ if (strlcpy(config_file, conf, sizeof config_file) = sizeof(config_file)) @@ -371,9 +371,9 @@ priv_init(char *conf, int numeric, int l /* Unlink any domain sockets that have been opened */ for (i = 0; i nunix; i++) - if (pfd[PFD_UNIX_0 + i].fd != -1) + if (fd_unix[i] != -1) (void)unlink(path_unix[i]); - if (path_ctlsock != NULL pfd[PFD_CTLSOCK].fd != -1) + if (path_ctlsock != NULL fd_ctlsock != -1) (void)unlink(path_ctlsock); if (restart) { Index: usr.sbin/syslogd/syslogd.c === RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v retrieving revision 1.127 diff -u -p -u -p -r1.127 syslogd.c --- usr.sbin/syslogd/syslogd.c3 Oct 2014 21:55:22 - 1.127 +++ usr.sbin/syslogd/syslogd.c3 Oct 2014 23:09:30 - @@ -50,6 +50,7 @@ * extensive changes by Ralph Campbell * more extensive changes by Eric Allman (again) * memory buffer logging by Damien Miller + * IPv6, libevent by Alexander Bluhm */ #define MAXLINE 1024/* maximum line length */ @@ -81,6 +82,7 @@ #include ctype.h #include errno.h #include err.h +#include event.h #include fcntl.h #include paths.h #include poll.h @@ -248,23 +250,28 @@ size_t ctl_reply_offset = 0; /* Number o char *linebuf; int linesize; -void klog_read_handler(int); -void udp_read_handler(int); -void unix_read_handler(int); - -struct pollfd pfd[N_PFD]; - -volatile sig_atomic_t MarkSet; -volatile sig_atomic_t WantDie; -volatile sig_atomic_t DoInit; +int fd_ctlsock, fd_ctlconn, fd_klog, fd_sendsys, + fd_udp, fd_udp6, fd_unix[MAXUNIX]; +struct event ev_ctlaccept, ev_ctlread, ev_ctlwrite, ev_klog, ev_sendsys, + ev_udp, ev_udp6, ev_unix[MAXUNIX], + ev_hup, ev_int, ev_quit, ev_term, ev_mark; + +void klog_readcb(int, short, void *); +void udp_readcb(int, short, void *); +void unix_readcb(int, short, void *); +void die_signalcb(int, short, void *); +void mark_timercb(int, short, void *); +void init_signalcb(int, short, void *); +void ctlsock_acceptcb(int, short, void *); +void
Re: syslogd libevent
On Sat, Oct 04, 2014 at 09:03:58AM +0100, Nicholas Marriott wrote: This should be: LDADD= -levent DPADD= ${LIBEVENT} Rather than LDFLAGS. Here is the updated diff. Index: usr.sbin/syslogd/Makefile === RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/Makefile,v retrieving revision 1.5 diff -u -p -r1.5 Makefile --- usr.sbin/syslogd/Makefile 4 Jan 2004 08:28:49 - 1.5 +++ usr.sbin/syslogd/Makefile 4 Oct 2014 09:17:53 - @@ -3,5 +3,7 @@ PROG= syslogd SRCS= syslogd.c ttymsg.c privsep.c privsep_fdpass.c ringbuf.c MAN= syslogd.8 syslog.conf.5 +LDADD= -levent +DPADD= ${LIBEVENT} .include bsd.prog.mk Index: usr.sbin/syslogd/privsep.c === RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v retrieving revision 1.47 diff -u -p -r1.47 privsep.c --- usr.sbin/syslogd/privsep.c 3 Oct 2014 21:55:22 - 1.47 +++ usr.sbin/syslogd/privsep.c 4 Oct 2014 09:17:25 - @@ -171,21 +171,21 @@ priv_init(char *conf, int numeric, int l close(socks[1]); /* Close descriptors that only the unpriv child needs */ + if (fd_ctlconn != -1) + close(fd_ctlconn); + if (fd_ctlsock != -1) + close(fd_ctlsock); + if (fd_klog != -1) + close(fd_klog); + if (fd_sendsys != -1) + close(fd_sendsys); + if (fd_udp != -1) + close(fd_udp); + if (fd_udp6 != -1) + close(fd_udp6); for (i = 0; i nunix; i++) - if (pfd[PFD_UNIX_0 + i].fd != -1) - close(pfd[PFD_UNIX_0 + i].fd); - if (pfd[PFD_INET].fd != -1) - close(pfd[PFD_INET].fd); - if (pfd[PFD_INET6].fd != -1) - close(pfd[PFD_INET6].fd); - if (pfd[PFD_CTLSOCK].fd != -1) - close(pfd[PFD_CTLSOCK].fd); - if (pfd[PFD_CTLCONN].fd != -1) - close(pfd[PFD_CTLCONN].fd); - if (pfd[PFD_KLOG].fd != -1) - close(pfd[PFD_KLOG].fd); - if (pfd[PFD_SENDSYS].fd != -1) - close(pfd[PFD_SENDSYS].fd); + if (fd_unix[i] != -1) + close(fd_unix[i]); /* Save the config file specified by the child process */ if (strlcpy(config_file, conf, sizeof config_file) = sizeof(config_file)) @@ -371,9 +371,9 @@ priv_init(char *conf, int numeric, int l /* Unlink any domain sockets that have been opened */ for (i = 0; i nunix; i++) - if (pfd[PFD_UNIX_0 + i].fd != -1) + if (fd_unix[i] != -1) (void)unlink(path_unix[i]); - if (path_ctlsock != NULL pfd[PFD_CTLSOCK].fd != -1) + if (path_ctlsock != NULL fd_ctlsock != -1) (void)unlink(path_ctlsock); if (restart) { Index: usr.sbin/syslogd/syslogd.c === RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v retrieving revision 1.127 diff -u -p -r1.127 syslogd.c --- usr.sbin/syslogd/syslogd.c 3 Oct 2014 21:55:22 - 1.127 +++ usr.sbin/syslogd/syslogd.c 4 Oct 2014 09:17:25 - @@ -50,6 +50,7 @@ * extensive changes by Ralph Campbell * more extensive changes by Eric Allman (again) * memory buffer logging by Damien Miller + * IPv6, libevent by Alexander Bluhm */ #defineMAXLINE 1024/* maximum line length */ @@ -81,6 +82,7 @@ #include ctype.h #include errno.h #include err.h +#include event.h #include fcntl.h #include paths.h #include poll.h @@ -248,23 +250,28 @@ size_tctl_reply_offset = 0; /* Number o char *linebuf; int linesize; -voidklog_read_handler(int); -voidudp_read_handler(int); -voidunix_read_handler(int); - -struct pollfd pfd[N_PFD]; - -volatile sig_atomic_t MarkSet; -volatile sig_atomic_t WantDie; -volatile sig_atomic_t DoInit; +int fd_ctlsock, fd_ctlconn, fd_klog, fd_sendsys, +fd_udp, fd_udp6, fd_unix[MAXUNIX]; +struct eventev_ctlaccept, ev_ctlread, ev_ctlwrite, ev_klog, ev_sendsys, +ev_udp, ev_udp6, ev_unix[MAXUNIX], +ev_hup, ev_int, ev_quit, ev_term, ev_mark; + +voidklog_readcb(int, short, void *); +voidudp_readcb(int, short, void *); +voidunix_readcb(int, short, void *); +voiddie_signalcb(int, short, void *); +voidmark_timercb(int, short, void *); +voidinit_signalcb(int, short, void *); +voidctlsock_acceptcb(int, short, void *); +voidctlconn_readcb(int, short, void *); +voidctlconn_writecb(int, short, void *); +voidctlconn_logto(char *); +voidctlconn_cleanup(void); struct filed *cfline(char *, char *); void cvthname(struct sockaddr *, char *, size_t); intdecode(const char *, const CODE *); -void dodie(int); -void doinit(int); void die(int); -void domark(int);
groupdel(8): preserve `+' line
groupdel(8) will complain (and delete) lines which do not have exactly three colon characters in them. This is annoying in yp environments where the last line of /etc/group is usually a single `+' character, which is equivalent to `+:*::' Invoking groupdel when /etc/group contains a final `+' line yields: # groupdel foo userdel: Malformed entry `+'. Skipping and the `+' line disappears. The following diff attempts to recognize and preserve such a line. Index: user.c === RCS file: /cvs/src/usr.sbin/user/user.c,v retrieving revision 1.100 diff -u -p -r1.100 user.c --- user.c 27 Aug 2014 06:51:35 - 1.100 +++ user.c 4 Oct 2014 12:01:57 - @@ -1281,6 +1281,13 @@ rm_user_from_groups(char *login_name) } if (cc != 3) { buf[strcspn(buf, \n)] = '\0'; + + /* Preserve a malformed but historical `+' line */ + if (strcmp(buf, +) == 0) { + strlcat(buf, \n, sizeof buf); + goto do_write; + } + warnx(Malformed entry `%s'. Skipping, buf); continue; } @@ -1299,6 +1306,7 @@ rm_user_from_groups(char *login_name) cp++; } } +do_write: if (fwrite(buf, strlen(buf), 1, to) != 1) { warn(can't remove gid for `%s': short write to `%s', login_name, f);
Re: groupdel(8): preserve `+' line
Hi Miod, Miod Vallat wrote on Sat, Oct 04, 2014 at 12:05:48PM +: groupdel(8) That utility is grossly disgusting. It's a pity we can't delete it completely - we have no useable replacement for groupinfo(8). All the other group(8) commands could, imho, be tedu'ed... With respect to disgusting: The file user.c contains *four* static functions containing more or less identical code: creategid(), modify_gid(), append_group(), and rm_user_from_groups(), which you are touching. Note the nice, consistent naming, by the way. - creategid() uses fgetln(3), does no checking whatsoever, and just leaves all existing lines as they are, even completely broken ones. By the way, there are exactly two calls to creategid(), and the group argument is always empty. - modify_gid() uses fgets(3) with a LINE_MAX (2048) buffer - a limit that is neither documented in group(5) nor in groupmod(8), and expecting that people are aware of http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_397 makes little sense to me - it *deletes* the long line and continues with the next line. It also checks that each line contains at least one colon and again deletes offending lines. As an exception, it allows the special entry +. No further checks are done. - append_group() again uses fgets(3), again deletes long lines, again deletes lines without any colon - *NOT* even allowing + -, deletes trailing whitespace from lines the user will be added to (surprise! new feature), then has this terrific code: buf[(j = cc)] = '\0'; if (buf[strlen(buf) - 1] != ':') strlcat(buf, ,, sizeof(buf)); cc = strlcat(buf, user, sizeof(buf)) + 1; if (cc = sizeof(buf)) /* error handling */ buf[cc - 1] = '\n'; buf[cc] = '\0'; I mean, just in case strlen(buf) isn't = j = cc, let's do another call to strlen(3). But what if strlen(buf) is LINE_MAX-1? Does that result in silent omission of the comma, clobbering two user names together? No it doesn't, because the code would have errored out before with line too long, so the strlcat is obfuscation and should be replaced by a mere buf[cc++] = ','; buf[cc] = '\0', so the first three lines become just j = cc; if (buf[cc - 1] != ':') buf[cc++] = ','; buf[cc] = '\0'; Surprisingly, the + 1 before the overflow check is actually correct, though cc = strlcat(buf, user, sizeof(buf)); if (cc + 1 = sizeof(buf)) /* error handling */ buf[cc++] = '\n'; buf[cc] = '\0'; would no doubt be clearer. - rm_user_from_groups() uses fgets(3), too, again deleting long lines, even those that would become short enough by removing the user. But it does much stricter error checking than all the other functions. It requires exactly three colons - as Miod observed, not allowing +. So error checking is different in each of the functions. I did not even check whether the duplicate parts of the code - dozens of lines in each of the functions - are identical or maybe contain subtle differences. Do people run this crap as root? I wonder. I certainly don't. If anybody cares, anybody should clean it up. Otherwise, i volunteer to delete all the parts that require write access and just leave those that merely need read access, i.e. don't need to run as root. I certainly don't volunteer to do the required cleanup. I'm not surprised the code is so shitty. I heard a talk by the author, Alistair G. Crooks, at EuroBSDCon in Karlsruhe, and it was about as bad as the code. will complain (and delete) lines which do not have exactly three colon characters in them. This is annoying in yp environments where the last line of /etc/group is usually a single `+' character, which is equivalent to `+:*::' Invoking groupdel when /etc/group contains a final `+' line yields: # groupdel foo Groupdel? Cannot reproduce. That's not broken in this way, but certainly in some other ways. I guess you mean userdel, somehow your cut paste failed, i guess: userdel: Malformed entry `+'. Skipping and the `+' line disappears. The following diff attempts to recognize and preserve such a line. Your diff correctly applies lipstick to the lower lip of the pig, forgetting about the upper lip, though (append_group()) - and about all the turds at the other end of the pig, of course. So this only helps with userdel(8), and with usermod(8) -S '' if and only if the user is removed from all groups. With usermod(8) -S somegroups, the failure mode is shifted to append_group() if the user is left in somegroups. That said, OK schwarze@ for either your version of the diff, or the modified one below, which is slightly simpler and has the same effect. Yours, Ingo Index: user.c === RCS file:
Re: groupdel(8): preserve `+' line
That utility is grossly disgusting. It's a pity we can't delete it completely [...] Why not? :-)
Re: groupdel(8): preserve `+' line
Do people run this crap as root? I wonder. I certainly don't. Yes. Just like useradd and such. These historical tools are harcoded in so many places and are expected to be present. That said, having someone rewrites them in a sane way would be awesome. -- Antoine
Re: groupdel(8): preserve `+' line
[snip rant] Do people run this crap as root? I wonder. I certainly don't. Then you might want to suggest an alternative to pkg_delete's ``You should also run /usr/sbin/groupdel _foo'' messages.
Re: groupdel(8): preserve `+' line
[snip rant] Do people run this crap as root? I wonder. I certainly don't. Then you might want to suggest an alternative to pkg_delete's ``You should also run /usr/sbin/groupdel _foo'' messages. Well, the rant is true. Both sets of user/group tools are written to an abominably low standard. Perhaps because there are two horrible ones, this has stopped people from wading in. Also, it can only be done by someone who already has a HazMat suit, since now they are hard to come by.
Re: groupdel(8): preserve `+' line
Hi Theo, Theo de Raadt wrote on Sat, Oct 04, 2014 at 11:37:21AM -0600: Ingo Schwarze wrote: That utility is grossly disgusting. It's a pity we can't delete it completely [...] Why not? Well, in a non-YP environment, grep ^foobar /etc/group is just fine, but in a YP environment, i'm not aware of any useable replacement for groupinfo(8): schwarze@iris $ grep mail /etc/group schwarze@iris $ ypmatch mail group mail:*:8:mail schwarze@iris $ groupinfo mail namemail passwd * gid 8 members mail schwarze@iris $ grep dialer /etc/group dialer:*:117:schwarze schwarze@iris $ ypmatch dialer group Can't match key dialer in map group.byname. Reason: No such key in map schwarze@iris $ groupinfo dialer namedialer passwd * gid 117 members schwarze schwarze@iris $ The only useful parts are userinfo(8) and groupinfo(8), and only in YP environments. :-) Oh hell, in case we all agree that i can delete all the rest, i volunteer to rewrite userinfo(8) and groupinfo(8) from scratch, how difficult can it be. Yours, Ingo
Re: mpe patch: use rt_ifa_{add,del}
On Thu, Oct 02, 2014 at 02:36:12PM +0200, Martin Pieuchot wrote: On 01/10/14(Wed) 21:54, Rafael Zalamena wrote: --- old chat snip --- Code change: * Moved label address from softc to lladdr ifa I'm afraid this is not what we want. The rest of your diff looks fine but moving the storage to be represented as a 'destination address' might make sense, but not attached on the lladdr ifa. I tried to use ifp-if_addrlist, but it looks like this KASSERT in rtsock.c doesn't like this. rtsock.c:1322 TAILQ_FOREACH(ifa, ifp-if_addrlist, ifa_list) { KASSERT(ifa-ifa_addr-sa_family != AF_LINK); See sys/net/rtsock.c: revision 1.144 Do not put any link-layer address on the per-ifp lists or on the RB- Tree. Since interfaces only support one link-layer address accessible via the if_sadl member, there's no need to have it elsewhere. This improves various address lookups because the first element of the list, the link- layer address, won't necessarily be discarded. Finally remove the empty netmask associated to every link-layer address. This hack was needed to (ab)use the address netmask comparison code to do a strcmp() on the interface name embedded in the sdl_data field. ok henning@, claudio@ So I moved the ifa back to softc. * Changed rt_ifa_add to default RTF_MPLS routes to do a POP and only use rdomain 0 (MPLS only works on domain 0, and it doesn't make sense other actions when creating MPLS route to an interface) Also changed rt_ifa_del() to remove routes from rdomain 0 as well. * Removed old code that installed mpe MPLS routes * Conflicting labels verification is now done by routing (see rt_ifa_add()) I had to put back the old verification for installed routes, since the rt_ifa_add checks failed to find already existing routes when changing domains or having mpe interfaces down. This looks ok. This was tested in the setup described in: http://2011.eurobsdcon.org/papers/jeker/MPLS.pdf Here is the diff: --- snipped old diff --- Updated diff: Index: net/if_mpe.c === RCS file: /home/rzalamena/obsdcvs//src/sys/net/if_mpe.c,v retrieving revision 1.35 diff -u -p -r1.35 if_mpe.c --- net/if_mpe.c22 Jul 2014 11:06:09 - 1.35 +++ net/if_mpe.c4 Oct 2014 22:21:17 - @@ -61,7 +61,6 @@ int mpeioctl(struct ifnet *, u_long, cad void mpestart(struct ifnet *); intmpe_clone_create(struct if_clone *, int); intmpe_clone_destroy(struct ifnet *); -intmpe_newlabel(struct ifnet *, int, struct shim_hdr *); LIST_HEAD(, mpe_softc) mpeif_list; struct if_clonempe_cloner = @@ -84,13 +83,19 @@ mpe_clone_create(struct if_clone *ifc, i { struct ifnet*ifp; struct mpe_softc*mpeif; + struct sockaddr_mpls*smpls; int s; if ((mpeif = malloc(sizeof(*mpeif), M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) return (ENOMEM); - mpeif-sc_shim.shim_label = 0; + smpls = malloc(sizeof(*smpls), M_IFADDR, M_NOWAIT | M_ZERO); + if (smpls == NULL) { + free(mpeif, M_DEVBUF, 0); + return (ENOMEM); + } + mpeif-sc_unit = unit; ifp = mpeif-sc_if; snprintf(ifp-if_xname, sizeof ifp-if_xname, mpe%d, unit); @@ -110,6 +115,12 @@ mpe_clone_create(struct if_clone *ifc, i bpfattach(ifp-if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); #endif + smpls-smpls_family = AF_MPLS; + smpls-smpls_len = sizeof(*smpls); + mpeif-sc_ifa.ifa_ifp = ifp; + mpeif-sc_ifa.ifa_addr = (struct sockaddr *) ifp-if_sadl; + mpeif-sc_ifa.ifa_dstaddr = smplstosa(smpls); + s = splnet(); LIST_INSERT_HEAD(mpeif_list, mpeif, sc_list); splx(s); @@ -128,6 +139,7 @@ mpe_clone_destroy(struct ifnet *ifp) splx(s); if_detach(ifp); + free(mpeif-sc_ifa.ifa_dstaddr, M_IFADDR, 0); free(mpeif, M_DEVBUF, 0); return (0); } @@ -278,8 +290,9 @@ int mpeioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { int error; - struct mpe_softc*ifm; + struct mpe_softc*ifm, *ifmn; struct ifreq*ifr; + struct sockaddr_mpls*smpls; struct shim_hdr shim; ifr = (struct ifreq *)data; @@ -304,13 +317,15 @@ mpeioctl(struct ifnet *ifp, u_long cmd, break; case SIOCGETLABEL: ifm = ifp-if_softc; + smpls = satosmpls(ifm-sc_ifa.ifa_dstaddr); shim.shim_label = - ((ntohl(ifm-sc_shim.shim_label MPLS_LABEL_MASK)) + ((ntohl(smpls-smpls_label MPLS_LABEL_MASK)) MPLS_LABEL_OFFSET); error = copyout(shim, ifr-ifr_data, sizeof(shim)); break; case SIOCSETLABEL: ifm =