Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net Introduce if_get, if_get_byindex and if_put



details:   https://anonhg.NetBSD.org/src/rev/b92b8d623d8c
branches:  trunk
changeset: 815412:b92b8d623d8c
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Mon May 16 01:06:31 2016 +0000

description:
Introduce if_get, if_get_byindex and if_put

The new API enables to obtain an ifnet object with protected by psref(9).
It is intended to be used where an obtained ifnet object is used over
sleepable operations.

diffstat:

 sys/net/if.c |  84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 sys/net/if.h |   8 +++--
 2 files changed, 87 insertions(+), 5 deletions(-)

diffs (140 lines):

diff -r 31cdc685557b -r b92b8d623d8c sys/net/if.c
--- a/sys/net/if.c      Sun May 15 23:54:58 2016 +0000
+++ b/sys/net/if.c      Mon May 16 01:06:31 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if.c,v 1.334 2016/05/12 02:24:16 ozaki-r Exp $ */
+/*     $NetBSD: if.c,v 1.335 2016/05/16 01:06:31 ozaki-r Exp $ */
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.334 2016/05/12 02:24:16 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.335 2016/05/16 01:06:31 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -2119,12 +2119,92 @@
        return ifp;
 }
 
+/*
+ * Get a reference of an ifnet object by an interface name.
+ * The returned reference is protected by psref(9). The caller
+ * must release a returned reference by if_put after use.
+ */
+struct ifnet *
+if_get(const char *name, struct psref *psref)
+{
+       struct ifnet *ifp;
+       const char *cp = name;
+       u_int unit = 0;
+       u_int i;
+       int s;
+
+       /*
+        * If the entire name is a number, treat it as an ifindex.
+        */
+       for (i = 0; i < IFNAMSIZ && *cp >= '0' && *cp <= '9'; i++, cp++) {
+               unit = unit * 10 + (*cp - '0');
+       }
+
+       /*
+        * If the number took all of the name, then it's a valid ifindex.
+        */
+       if (i == IFNAMSIZ || (cp != name && *cp == '\0')) {
+               if (unit >= if_indexlim)
+                       return NULL;
+               ifp = ifindex2ifnet[unit];
+               if (ifp == NULL || ifp->if_output == if_nulloutput)
+                       return NULL;
+               return ifp;
+       }
+
+       ifp = NULL;
+       s = pserialize_read_enter();
+       IFNET_READER_FOREACH(ifp) {
+               if (ifp->if_output == if_nulloutput)
+                       continue;
+               if (strcmp(ifp->if_xname, name) == 0) {
+                       psref_acquire(psref, &ifp->if_psref,
+                           ifnet_psref_class);
+                       goto out;
+               }
+       }
+out:
+       pserialize_read_exit(s);
+       return ifp;
+}
+
+/*
+ * Release a reference of an ifnet object given by if_get or
+ * if_get_byindex.
+ */
+void
+if_put(const struct ifnet *ifp, struct psref *psref)
+{
+
+       psref_release(psref, &ifp->if_psref, ifnet_psref_class);
+}
+
 ifnet_t *
 if_byindex(u_int idx)
 {
        return (idx < if_indexlim) ? ifindex2ifnet[idx] : NULL;
 }
 
+/*
+ * Get a reference of an ifnet object by an interface index.
+ * The returned reference is protected by psref(9). The caller
+ * must release a returned reference by if_put after use.
+ */
+ifnet_t *
+if_get_byindex(u_int idx, struct psref *psref)
+{
+       ifnet_t *ifp;
+       int s;
+
+       s = pserialize_read_enter();
+       ifp = (idx < if_indexlim) ? ifindex2ifnet[idx] : NULL;
+       if (ifp != NULL)
+               psref_acquire(psref, &ifp->if_psref, ifnet_psref_class);
+       pserialize_read_exit(s);
+
+       return ifp;
+}
+
 /* common */
 int
 ifioctl_common(struct ifnet *ifp, u_long cmd, void *data)
diff -r 31cdc685557b -r b92b8d623d8c sys/net/if.h
--- a/sys/net/if.h      Sun May 15 23:54:58 2016 +0000
+++ b/sys/net/if.h      Mon May 16 01:06:31 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if.h,v 1.204 2016/05/12 02:24:16 ozaki-r Exp $ */
+/*     $NetBSD: if.h,v 1.205 2016/05/16 01:06:31 ozaki-r Exp $ */
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -912,6 +912,10 @@
 int    ifioctl_common(struct ifnet *, u_long, void *);
 int    ifpromisc(struct ifnet *, int);
 struct ifnet *ifunit(const char *);
+struct ifnet *if_get(const char *, struct psref *);
+ifnet_t *if_byindex(u_int);
+ifnet_t *if_get_byindex(u_int, struct psref *);
+void   if_put(const struct ifnet *, struct psref *);
 int    if_addr_init(ifnet_t *, struct ifaddr *, bool);
 int    if_do_dad(struct ifnet *);
 int    if_mcast_op(ifnet_t *, const unsigned long, const struct sockaddr *);
@@ -1047,8 +1051,6 @@
 
 extern struct ifnet *lo0ifp;
 
-ifnet_t *      if_byindex(u_int);
-
 /*
  * ifq sysctl support
  */



Home | Main Index | Thread Index | Old Index