diff options
-rw-r--r-- | share/man/man4/bridge.4 | 15 | ||||
-rw-r--r-- | sys/net/if_bridge.c | 62 | ||||
-rw-r--r-- | sys/net/if_bridge.h | 4 | ||||
-rw-r--r-- | sys/sys/sockio.h | 4 | ||||
-rw-r--r-- | usr.sbin/brconfig/brconfig.8 | 13 | ||||
-rw-r--r-- | usr.sbin/brconfig/brconfig.c | 85 |
6 files changed, 173 insertions, 10 deletions
diff --git a/share/man/man4/bridge.4 b/share/man/man4/bridge.4 index b143a1eccbd..28c658c769c 100644 --- a/share/man/man4/bridge.4 +++ b/share/man/man4/bridge.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bridge.4,v 1.5 1999/03/12 02:40:42 jason Exp $ +.\" $OpenBSD: bridge.4,v 1.6 1999/03/19 02:46:54 jason Exp $ .\" .\" Copyright (c) 1999 Jason L. Wright (jason@thought.net) .\" All rights reserved. @@ -94,6 +94,8 @@ struct ifbreq { u_int32_t ifbr_ifsflags; /* member flags */ }; +#define IFBIF_LEARNING 0x1 /* ifs can learn addrs */ + struct ifbifconf { char ifbic_name[IFNAMSIZ]; /* bridge name */ u_int32_t ifbic_len; /* buffer size */ @@ -117,6 +119,17 @@ Delete the interface named in .Ar ifbr_ifsname from the bridge named in .Ar ifbr_name . +.It Dv SIOCBRDGSIFFLGS +.Pq Li "struct ifbreq" +Set the bridge member interface flags for the interface named in +.Ar ifbr_ifsname +attached to the bridge +.Ar ifbr_name . +.It Dv SIOCBRDGGIFFLGS +Retrieve the bridge member interface flags for the interface named in +.Ar ifbr_ifsname +attached to the bridge +.Ar ifbr_name . .It Dv SIOCBRDGRTS .Pq Li "struct ifbaconf" Retrieve the address cache of the bridge named in diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index cc777402272..9e3ed260c65 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.6 1999/03/12 02:40:43 jason Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.7 1999/03/19 02:46:54 jason Exp $ */ /* * Copyright (c) 1999 Jason L. Wright (jason@thought.net) @@ -280,6 +280,7 @@ bridge_ioctl(ifp, cmd, data) } p->ifp = ifs; + p->bif_flags = IFBIF_LEARNING; LIST_INSERT_HEAD(&sc->sc_iflist, p, next); ifs->if_bridge = (caddr_t)sc; break; @@ -310,6 +311,48 @@ bridge_ioctl(ifp, cmd, data) case SIOCBRDGIFS: error = bridge_bifconf(sc, bifconf); break; + case SIOCBRDGGIFFLGS: + ifs = ifunit(req->ifbr_ifsname); + if (ifs == NULL) { + error = ENOENT; + break; + } + if ((caddr_t)sc != ifs->if_bridge) { + error = ESRCH; + break; + } + p = LIST_FIRST(&sc->sc_iflist); + while (p != NULL && p->ifp != ifs) { + p = LIST_NEXT(p, next); + } + if (p == NULL) { + error = ESRCH; + break; + } + req->ifbr_ifsflags = p->bif_flags; + break; + case SIOCBRDGSIFFLGS: + if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) + break; + ifs = ifunit(req->ifbr_ifsname); + if (ifs == NULL) { + error = ENOENT; + break; + } + if ((caddr_t)sc != ifs->if_bridge) { + error = ESRCH; + break; + } + p = LIST_FIRST(&sc->sc_iflist); + while (p != NULL && p->ifp != ifs) { + p = LIST_NEXT(p, next); + } + if (p == NULL) { + error = ESRCH; + break; + } + p->bif_flags = req->ifbr_ifsflags; + break; case SIOCBRDGRTS: if ((ifp->if_flags & IFF_RUNNING) == 0) { error = ENETDOWN; @@ -643,6 +686,7 @@ bridge_input(ifp, eh, m) struct arpcom *ac; struct ether_addr *dst, *src; struct ifnet *dst_if; + struct bridge_iflist *ifl; int s; /* @@ -677,11 +721,21 @@ bridge_input(ifp, eh, m) dst = (struct ether_addr *)&eh->ether_dhost[0]; src = (struct ether_addr *)&eh->ether_shost[0]; + ifl = LIST_FIRST(&sc->sc_iflist); + while (ifl != NULL && ifl->ifp != ifp) { + ifl = LIST_NEXT(ifl, next); + } + if (ifl == NULL) { + splx(s); + return (m); + } + /* - * If source address is not broadcast or multicast, record - * it's address. + * If interface is learning, and if source address is not broadcast + * or multicast, record it's address. */ - if ((eh->ether_shost[0] & 1) == 0 && + if ((ifl->bif_flags & IFBIF_LEARNING) && + (eh->ether_shost[0] & 1) == 0 && !(eh->ether_shost[0] == 0 && eh->ether_shost[1] == 0 && eh->ether_shost[2] == 0 && eh->ether_shost[3] == 0 && eh->ether_shost[4] == 0 && eh->ether_shost[5] == 0)) diff --git a/sys/net/if_bridge.h b/sys/net/if_bridge.h index 7838fdf2c6f..6ebcccf5df1 100644 --- a/sys/net/if_bridge.h +++ b/sys/net/if_bridge.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.h,v 1.4 1999/03/12 02:40:43 jason Exp $ */ +/* $OpenBSD: if_bridge.h,v 1.5 1999/03/19 02:46:54 jason Exp $ */ /* * Copyright (c) 1999 Jason L. Wright (jason@thought.net) @@ -40,6 +40,8 @@ struct ifbreq { u_int32_t ifbr_ifsflags; /* memver ifs flags */ }; +#define IFBIF_LEARNING 0x1 /* ifs can learn */ + /* * Interface list structure */ diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h index aad00f61001..28211d2613f 100644 --- a/sys/sys/sockio.h +++ b/sys/sys/sockio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sockio.h,v 1.8 1999/03/12 02:40:43 jason Exp $ */ +/* $OpenBSD: sockio.h,v 1.9 1999/03/19 02:46:55 jason Exp $ */ /* $NetBSD: sockio.h,v 1.5 1995/08/23 00:40:47 thorpej Exp $ */ /*- @@ -85,6 +85,8 @@ #define SIOCBRDGADD _IOWR('i', 60, struct ifbreq) /* add bridge ifs */ #define SIOCBRDGDEL _IOWR('i', 61, struct ifbreq) /* del bridge ifs */ +#define SIOCBRDGGIFFLGS _IOWR('i', 62, struct ifbreq) /* get brdg if flags */ +#define SIOCBRDGSIFFLGS _IOWR('i', 63, struct ifbreq) /* set brdg if flags */ #define SIOCBRDGSCACHE _IOWR('i', 64, struct ifbcachereq) /* set cache size */ #define SIOCBRDGGCACHE _IOWR('i', 65, struct ifbcachereq) /* get cache size */ #define SIOCBRDGIFS _IOWR('i', 66, struct ifbreq) /* get member ifs */ diff --git a/usr.sbin/brconfig/brconfig.8 b/usr.sbin/brconfig/brconfig.8 index 453d5baa589..19958a412ae 100644 --- a/usr.sbin/brconfig/brconfig.8 +++ b/usr.sbin/brconfig/brconfig.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: brconfig.8,v 1.7 1999/03/12 02:40:43 jason Exp $ +.\" $OpenBSD: brconfig.8,v 1.8 1999/03/19 02:46:55 jason Exp $ .\" .\" Copyright (c) 1999 Jason L. Wright (jason@thought.net) .\" All rights reserved. @@ -51,6 +51,8 @@ .Op Ar deladdr address .Op Ar flush .Op Ar flushall +.Op Ar learn interface-name +.Op Ar -learn interface-name .Op Ar link0 .Op Ar link1 .Op Ar -link0 @@ -115,6 +117,15 @@ Delete an address from the cache. Remove all dynamically learned addresses from the cache. .It Ar flushall Remove all addresses from the cache including static addresses. +.It Ar learn interface +Mark an interface so that the source address of packets received from +.Cm interface +are entered into the address cache. +This is the default for interfaces added to the bridge. +.It Ar -learn interface +Mark an interface so that the source address of packets received from +.Cm interface +are not entered into the address cache. .It Ar link0 Setting this flag stops all non-IP multicast packets from being forwarded by the bridge. diff --git a/usr.sbin/brconfig/brconfig.c b/usr.sbin/brconfig/brconfig.c index 5da432f282c..66ef54c23b6 100644 --- a/usr.sbin/brconfig/brconfig.c +++ b/usr.sbin/brconfig/brconfig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: brconfig.c,v 1.7 1999/03/12 23:19:26 deraadt Exp $ */ +/* $OpenBSD: brconfig.c,v 1.8 1999/03/19 02:46:55 jason Exp $ */ /* * Copyright (c) 1999 Jason L. Wright (jason@thought.net) @@ -32,6 +32,7 @@ */ #include <stdio.h> +#include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <sys/param.h> @@ -53,6 +54,8 @@ void usage(void); int main(int, char **); int bridge_setflag(int, char *, short); int bridge_clrflag(int, char *, short); +int bridge_ifsetflag(int, char *, char *, u_int32_t); +int bridge_ifclrflag(int, char *, char *, u_int32_t); int bridge_list(int, char *, char *); int bridge_addrs(int, char *, char *); int bridge_addaddr(int, char *, char *, char *); @@ -74,6 +77,7 @@ void printb(char *, unsigned short, char *); \11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST" #define IFBABITS "\020\1STATIC" +#define IFBIBITS "\020\1LEARNING" void usage() @@ -148,6 +152,28 @@ main(argc, argv) if (error) return (error); } + else if (strcmp("learn", argv[0]) == 0) { + argc--; argv++; + if (argc == 0) { + warnx("learn requires an argument"); + return (EX_USAGE); + } + error = bridge_ifsetflag(sock, brdg, argv[0], + IFBIF_LEARNING); + if (error) + return (error); + } + else if (strcmp("-learn", argv[0]) == 0) { + argc--; argv++; + if (argc == 0) { + warnx("-learn requires an argument"); + return (EX_USAGE); + } + error = bridge_ifclrflag(sock, brdg, argv[0], + IFBIF_LEARNING); + if (error) + return (error); + } else if (strcmp("flush", argv[0]) == 0) { error = bridge_flush(sock, brdg); if (error) @@ -234,6 +260,59 @@ main(argc, argv) } int +bridge_ifsetflag(s, brdg, ifsname, flag) + int s; + char *brdg, *ifsname; + u_int32_t flag; +{ + struct ifbreq req; + + strncpy(req.ifbr_name, brdg, sizeof(req.ifbr_name) - 1); + req.ifbr_name[sizeof(req.ifbr_name) - 1] = '\0'; + strncpy(req.ifbr_ifsname, ifsname, sizeof(req.ifbr_ifsname) - 1); + req.ifbr_ifsname[sizeof(req.ifbr_ifsname) - 1] = '\0'; + if (ioctl(s, SIOCBRDGGIFFLGS, (caddr_t)&req) < 0) { + warn("ioctl(SIOCBRDGGIFFLGS)"); + return (EX_IOERR); + } + + req.ifbr_ifsflags |= flag; + + if (ioctl(s, SIOCBRDGSIFFLGS, (caddr_t)&req) < 0) { + warn("ioctl(SIOCBRDGSIFFLGS)"); + return (EX_IOERR); + } + return (0); +} + +int +bridge_ifclrflag(s, brdg, ifsname, flag) + int s; + char *brdg, *ifsname; + u_int32_t flag; +{ + struct ifbreq req; + + strncpy(req.ifbr_name, brdg, sizeof(req.ifbr_name) - 1); + req.ifbr_name[sizeof(req.ifbr_name) - 1] = '\0'; + strncpy(req.ifbr_ifsname, ifsname, sizeof(req.ifbr_ifsname) - 1); + req.ifbr_ifsname[sizeof(req.ifbr_ifsname) - 1] = '\0'; + + if (ioctl(s, SIOCBRDGGIFFLGS, (caddr_t)&req) < 0) { + warn("ioctl(SIOCBRDGGIFFLGS)"); + return (EX_IOERR); + } + + req.ifbr_ifsflags &= ~flag; + + if (ioctl(s, SIOCBRDGSIFFLGS, (caddr_t)&req) < 0) { + warn("ioctl(SIOCBRDGSIFFLGS)"); + return (EX_IOERR); + } + return (0); +} + +int bridge_show_all(s) int s; { @@ -408,7 +487,9 @@ bridge_list(s, brdg, delim) reqp = bifc.ifbic_req + i; bzero(buf, sizeof(buf)); strncpy(buf, reqp->ifbr_ifsname, sizeof(reqp->ifbr_ifsname)); - printf("%s%s\n", delim, buf); + printf("%s%s ", delim, buf); + printb("flags", reqp->ifbr_ifsflags, IFBIBITS); + printf("\n"); } free(bifc.ifbic_buf); return (0); /* NOTREACHED */ |