aboutsummaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorKip Macy <kmacy@FreeBSD.org>2009-04-16 22:04:07 +0000
committerKip Macy <kmacy@FreeBSD.org>2009-04-16 22:04:07 +0000
commitc8da95ace9a07ead9855ccd56da3c3f61bb0913b (patch)
tree4ccd3f7370cfdf8eca6a8f6d9cb14ff9327af3c9 /sys/net
parent279aa3d419d5bfaf514ed543ab177852e4c2b013 (diff)
downloadsrc-c8da95ace9a07ead9855ccd56da3c3f61bb0913b.tar.gz
src-c8da95ace9a07ead9855ccd56da3c3f61bb0913b.zip
add utility routine for updating an struct llentry *
Notes
Notes: svn path=/head/; revision=191154
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_llatbl.c33
-rw-r--r--sys/net/if_llatbl.h2
2 files changed, 35 insertions, 0 deletions
diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c
index 2287f92c7e95..d7fb37a2b040 100644
--- a/sys/net/if_llatbl.c
+++ b/sys/net/if_llatbl.c
@@ -103,6 +103,39 @@ llentry_free(struct llentry *lle)
LLE_FREE_LOCKED(lle);
}
+int
+llentry_update(struct llentry **llep, struct lltable *lt,
+ struct sockaddr *dst, struct ifnet *ifp)
+{
+ struct llentry *la;
+
+ IF_AFDATA_RLOCK(ifp);
+ la = lla_lookup(lt, LLE_EXCLUSIVE,
+ (struct sockaddr *)dst);
+ IF_AFDATA_RUNLOCK(ifp);
+ if ((la == NULL) &&
+ (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
+ IF_AFDATA_WLOCK(ifp);
+ la = lla_lookup(lt,
+ (LLE_CREATE | LLE_EXCLUSIVE),
+ (struct sockaddr *)dst);
+ IF_AFDATA_WUNLOCK(ifp);
+ }
+ if (la != NULL && (*llep != la)) {
+ if (*llep != NULL)
+ LLE_FREE(*llep);
+ LLE_ADDREF(la);
+ LLE_WUNLOCK(la);
+ *llep = la;
+ } else if (la != NULL)
+ LLE_WUNLOCK(la);
+
+ if (la == NULL)
+ return (ENOENT);
+
+ return (0);
+}
+
/*
* Free all entries from given table and free itself.
* Since lltables collects from all of the intefaces,
diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h
index 50e617d9d679..3b3086f75f76 100644
--- a/sys/net/if_llatbl.h
+++ b/sys/net/if_llatbl.h
@@ -178,6 +178,8 @@ void lltable_drain(int);
int lltable_sysctl_dumparp(int, struct sysctl_req *);
void llentry_free(struct llentry *);
+int llentry_update(struct llentry **, struct lltable *,
+ struct sockaddr *, struct ifnet *);
/*
* Generic link layer address lookup function.