summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/man/man4/bridge.415
-rw-r--r--sys/net/if_bridge.c62
-rw-r--r--sys/net/if_bridge.h4
-rw-r--r--sys/sys/sockio.h4
-rw-r--r--usr.sbin/brconfig/brconfig.813
-rw-r--r--usr.sbin/brconfig/brconfig.c85
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 */