Fix two bugs with the bridge
- code expects memcmp() to return a signed value, our memcmp() returns 0 if args are equal and > 0 if not. - It's possible to hijack interface for static entry. If bridge recieves packet from interface marked as learning it will replace the bridge_rtnode entry for the source address even if such entry marked as static. Submitted by: Gleb Kurtsov <k-gleb yandex.ru> MFC after: 3 days
This commit is contained in:
parent
2f4f3e134b
commit
6637e0f390
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=155143
@ -215,6 +215,7 @@ static int bridge_rtdaddr(struct bridge_softc *, const uint8_t *);
|
||||
static int bridge_rtable_init(struct bridge_softc *);
|
||||
static void bridge_rtable_fini(struct bridge_softc *);
|
||||
|
||||
static int bridge_rtnode_addr_cmp(const uint8_t *, const uint8_t *);
|
||||
static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
|
||||
const uint8_t *);
|
||||
static int bridge_rtnode_insert(struct bridge_softc *,
|
||||
@ -2193,7 +2194,8 @@ bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
|
||||
}
|
||||
}
|
||||
|
||||
brt->brt_ifp = dst_if;
|
||||
if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
|
||||
brt->brt_ifp = dst_if;
|
||||
if ((flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
|
||||
brt->brt_expire = time_uptime + sc->sc_brttimeout;
|
||||
if (setflags)
|
||||
@ -2424,6 +2426,18 @@ bridge_rthash(struct bridge_softc *sc, const uint8_t *addr)
|
||||
|
||||
#undef mix
|
||||
|
||||
static int
|
||||
bridge_rtnode_addr_cmp(const uint8_t *a, const uint8_t *b)
|
||||
{
|
||||
int i, d;
|
||||
|
||||
for (i = 0, d = 0; i < ETHER_ADDR_LEN && d == 0; i++) {
|
||||
d = ((int)a[i]) - ((int)b[i]);
|
||||
}
|
||||
|
||||
return (d);
|
||||
}
|
||||
|
||||
/*
|
||||
* bridge_rtnode_lookup:
|
||||
*
|
||||
@ -2440,7 +2454,7 @@ bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr)
|
||||
|
||||
hash = bridge_rthash(sc, addr);
|
||||
LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
|
||||
dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN);
|
||||
dir = bridge_rtnode_addr_cmp(addr, brt->brt_addr);
|
||||
if (dir == 0)
|
||||
return (brt);
|
||||
if (dir > 0)
|
||||
@ -2474,7 +2488,7 @@ bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
|
||||
}
|
||||
|
||||
do {
|
||||
dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN);
|
||||
dir = bridge_rtnode_addr_cmp(brt->brt_addr, lbrt->brt_addr);
|
||||
if (dir == 0)
|
||||
return (EEXIST);
|
||||
if (dir > 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user