summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorgjb <gjb@FreeBSD.org>2016-04-11 15:24:59 +0000
committergjb <gjb@FreeBSD.org>2016-04-11 15:24:59 +0000
commite0e3598ce13850597a66fd28d102b36881f7d610 (patch)
treef5194d1ce3fa45b67cf63080fc519fec83abc57a /sys/net
parentcbc3bd9845ba5fd58e8132f9565cfbc41433938d (diff)
parent26836fccd261358467b3d92e77ff4695af286de9 (diff)
downloadFreeBSD-src-e0e3598ce13850597a66fd28d102b36881f7d610.zip
FreeBSD-src-e0e3598ce13850597a66fd28d102b36881f7d610.tar.gz
MFH
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/bpf.c62
-rw-r--r--sys/net/bpf.h3
-rw-r--r--sys/net/if.c11
-rw-r--r--sys/net/if_gif.c2
-rw-r--r--sys/net/if_gre.c4
5 files changed, 79 insertions, 3 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 54dd184..5f2ef71 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include "opt_bpf.h"
#include "opt_compat.h"
+#include "opt_ddb.h"
#include "opt_netgraph.h"
#include <sys/types.h>
@@ -67,6 +68,10 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
+#ifdef DDB
+#include <ddb/ddb.h>
+#endif
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
@@ -2569,6 +2574,32 @@ bpfattach2(struct ifnet *ifp, u_int dlt, u_int hdrlen, struct bpf_if **driverp)
if_printf(ifp, "bpf attached\n");
}
+#ifdef VIMAGE
+/*
+ * When moving interfaces between vnet instances we need a way to
+ * query the dlt and hdrlen before detach so we can re-attch the if_bpf
+ * after the vmove. We unfortunately have no device driver infrastructure
+ * to query the interface for these values after creation/attach, thus
+ * add this as a workaround.
+ */
+int
+bpf_get_bp_params(struct bpf_if *bp, u_int *bif_dlt, u_int *bif_hdrlen)
+{
+
+ if (bp == NULL)
+ return (ENXIO);
+ if (bif_dlt == NULL && bif_hdrlen == NULL)
+ return (0);
+
+ if (bif_dlt != NULL)
+ *bif_dlt = bp->bif_dlt;
+ if (bif_hdrlen != NULL)
+ *bif_hdrlen = bp->bif_hdrlen;
+
+ return (0);
+}
+#endif
+
/*
* Detach bpf from an interface. This involves detaching each descriptor
* associated with the interface. Notify each descriptor as it's detached
@@ -2977,3 +3008,34 @@ bpf_validate(const struct bpf_insn *f, int len)
}
#endif /* !DEV_BPF && !NETGRAPH_BPF */
+
+#ifdef DDB
+static void
+bpf_show_bpf_if(struct bpf_if *bpf_if)
+{
+
+ if (bpf_if == NULL)
+ return;
+ db_printf("%p:\n", bpf_if);
+#define BPF_DB_PRINTF(f, e) db_printf(" %s = " f "\n", #e, bpf_if->e);
+ /* bif_ext.bif_next */
+ /* bif_ext.bif_dlist */
+ BPF_DB_PRINTF("%#x", bif_dlt);
+ BPF_DB_PRINTF("%u", bif_hdrlen);
+ BPF_DB_PRINTF("%p", bif_ifp);
+ /* bif_lock */
+ /* bif_wlist */
+ BPF_DB_PRINTF("%#x", bif_flags);
+}
+
+DB_SHOW_COMMAND(bpf_if, db_show_bpf_if)
+{
+
+ if (!have_addr) {
+ db_printf("usage: show bpf_if <struct bpf_if *>\n");
+ return;
+ }
+
+ bpf_show_bpf_if((struct bpf_if *)addr);
+}
+#endif
diff --git a/sys/net/bpf.h b/sys/net/bpf.h
index a74b521..0ffc15ac 100644
--- a/sys/net/bpf.h
+++ b/sys/net/bpf.h
@@ -1469,6 +1469,9 @@ void bpf_mtap2(struct bpf_if *, void *, u_int, struct mbuf *);
void bpfattach(struct ifnet *, u_int, u_int);
void bpfattach2(struct ifnet *, u_int, u_int, struct bpf_if **);
void bpfdetach(struct ifnet *);
+#ifdef VIMAGE
+int bpf_get_bp_params(struct bpf_if *, u_int *, u_int *);
+#endif
void bpfilterattach(int);
u_int bpf_filter(const struct bpf_insn *, u_char *, u_int, u_int);
diff --git a/sys/net/if.c b/sys/net/if.c
index b9e524c..2c44c87 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1021,8 +1021,16 @@ void
if_vmove(struct ifnet *ifp, struct vnet *new_vnet)
{
struct if_clone *ifc;
+ u_int bif_dlt, bif_hdrlen;
int rc;
+ /*
+ * if_detach_internal() will call the eventhandler to notify
+ * interface departure. That will detach if_bpf. We need to
+ * safe the dlt and hdrlen so we can re-attach it later.
+ */
+ bpf_get_bp_params(ifp->if_bpf, &bif_dlt, &bif_hdrlen);
+
/*
* Detach from current vnet, but preserve LLADDR info, do not
* mark as dead etc. so that the ifnet can be reattached later.
@@ -1062,6 +1070,9 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet)
if_attach_internal(ifp, 1, ifc);
+ if (ifp->if_bpf == NULL)
+ bpfattach(ifp, bif_dlt, bif_hdrlen);
+
CURVNET_RESTORE();
}
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index 1607af9..cfa4650 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -1023,7 +1023,7 @@ gif_set_tunnel(struct ifnet *ifp, struct sockaddr *src, struct sockaddr *dst)
#endif
default:
return (EAFNOSUPPORT);
- };
+ }
if (sc->gif_family != src->sa_family)
gif_detach(sc);
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index 9d4a976..425df8e 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -353,7 +353,7 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
if (error != 0)
goto end;
#endif
- };
+ }
error = gre_set_tunnel(ifp, src, dst);
break;
case SIOCDIFPHYADDR:
@@ -960,7 +960,7 @@ gre_transmit(struct ifnet *ifp, struct mbuf *m)
default:
m_freem(m);
error = ENETDOWN;
- };
+ }
drop:
if (error)
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
OpenPOWER on IntegriCloud