aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/netmap/netmap_kern.h
diff options
context:
space:
mode:
authorVincenzo Maffione <vmaffione@FreeBSD.org>2018-04-12 07:20:50 +0000
committerVincenzo Maffione <vmaffione@FreeBSD.org>2018-04-12 07:20:50 +0000
commit2ff91c175eca50b7d0d9da6b31eae4109c034137 (patch)
tree15a4f8847a8cabd782f67326125c48fed4fdd27b /sys/dev/netmap/netmap_kern.h
parent66def52613043a86172a2ebe6feab214258fa2fa (diff)
Notes
Diffstat (limited to 'sys/dev/netmap/netmap_kern.h')
-rw-r--r--sys/dev/netmap/netmap_kern.h155
1 files changed, 102 insertions, 53 deletions
diff --git a/sys/dev/netmap/netmap_kern.h b/sys/dev/netmap/netmap_kern.h
index 3e6451091324..8fc71b8e820e 100644
--- a/sys/dev/netmap/netmap_kern.h
+++ b/sys/dev/netmap/netmap_kern.h
@@ -77,7 +77,7 @@
#define WITH_GENERIC
#define WITH_PTNETMAP_HOST /* ptnetmap host support */
#define WITH_PTNETMAP_GUEST /* ptnetmap guest support */
-
+#define WITH_EXTMEM
#endif
#if defined(__FreeBSD__)
@@ -367,9 +367,6 @@ struct netmap_zmon_list {
* the next empty buffer as known by the hardware (next_to_check or so).
* TX rings: hwcur + hwofs coincides with next_to_send
*
- * For received packets, slot->flags is set to nkr_slot_flags
- * so we can provide a proper initial value.
- *
* The following fields are used to implement lock-free copy of packets
* from input to output ports in VALE switch:
* nkr_hwlease buffer after the last one being copied.
@@ -401,7 +398,7 @@ struct netmap_zmon_list {
struct netmap_kring {
struct netmap_ring *ring;
- uint32_t nr_hwcur;
+ uint32_t nr_hwcur; /* should be nr_hwhead */
uint32_t nr_hwtail;
/*
@@ -424,6 +421,7 @@ struct netmap_kring {
* by ptnetmap host ports)
*/
#define NKR_NOINTR 0x10 /* don't use interrupts on this ring */
+#define NKR_FAKERING 0x20 /* don't allocate/free buffers */
uint32_t nr_mode;
uint32_t nr_pending_mode;
@@ -450,7 +448,14 @@ struct netmap_kring {
NM_LOCK_T q_lock; /* protects kring and ring. */
NM_ATOMIC_T nr_busy; /* prevent concurrent syscalls */
+ /* the adapter the owns this kring */
struct netmap_adapter *na;
+
+ /* the adapter that wants to be notified when this kring has
+ * new slots avaialable. This is usually the same as the above,
+ * but wrappers may let it point to themselves
+ */
+ struct netmap_adapter *notify_na;
/* The following fields are for VALE switch support */
struct nm_bdg_fwd *nkr_ft;
@@ -630,6 +635,15 @@ struct netmap_lut {
struct netmap_vp_adapter; // forward
+/* Struct to be filled by nm_config callbacks. */
+struct nm_config_info {
+ unsigned num_tx_rings;
+ unsigned num_rx_rings;
+ unsigned num_tx_descs;
+ unsigned num_rx_descs;
+ unsigned rx_buf_maxsize;
+};
+
/*
* The "struct netmap_adapter" extends the "struct adapter"
* (or equivalent) device descriptor.
@@ -690,8 +704,8 @@ struct netmap_adapter {
* as a contiguous chunk of memory. Each array has
* N+1 entries, for the adapter queues and for the host queue.
*/
- struct netmap_kring *tx_rings; /* array of TX rings. */
- struct netmap_kring *rx_rings; /* array of RX rings. */
+ struct netmap_kring **tx_rings; /* array of TX rings. */
+ struct netmap_kring **rx_rings; /* array of RX rings. */
void *tailroom; /* space below the rings array */
/* (used for leases) */
@@ -766,8 +780,7 @@ struct netmap_adapter {
#define NAF_FORCE_RECLAIM 2
#define NAF_CAN_FORWARD_DOWN 4
/* return configuration information */
- int (*nm_config)(struct netmap_adapter *,
- u_int *txr, u_int *txd, u_int *rxr, u_int *rxd);
+ int (*nm_config)(struct netmap_adapter *, struct nm_config_info *info);
int (*nm_krings_create)(struct netmap_adapter *);
void (*nm_krings_delete)(struct netmap_adapter *);
#ifdef WITH_VALE
@@ -787,7 +800,7 @@ struct netmap_adapter {
* Called with NMG_LOCK held.
*/
int (*nm_bdg_attach)(const char *bdg_name, struct netmap_adapter *);
- int (*nm_bdg_ctl)(struct netmap_adapter *, struct nmreq *, int);
+ int (*nm_bdg_ctl)(struct nmreq_header *, struct netmap_adapter *);
/* adapter used to attach this adapter to a VALE switch (if any) */
struct netmap_vp_adapter *na_vp;
@@ -823,7 +836,13 @@ struct netmap_adapter {
/* Offset of ethernet header for each packet. */
u_int virt_hdr_len;
- char name[64];
+ /* Max number of bytes that the NIC can store in the buffer
+ * referenced by each RX descriptor. This translates to the maximum
+ * bytes that a single netmap slot can reference. Larger packets
+ * require NS_MOREFRAG support. */
+ unsigned rx_buf_maxsize;
+
+ char name[NETMAP_REQ_IFNAMSIZ]; /* used at least by pipes */
};
static __inline u_int
@@ -856,7 +875,7 @@ nma_set_nrings(struct netmap_adapter *na, enum txrx t, u_int v)
na->num_rx_rings = v;
}
-static __inline struct netmap_kring*
+static __inline struct netmap_kring**
NMR(struct netmap_adapter *na, enum txrx t)
{
return (t == NR_TX ? na->tx_rings : na->rx_rings);
@@ -1011,12 +1030,22 @@ struct netmap_bwrap_adapter {
*/
struct netmap_priv_d *na_kpriv;
struct nm_bdg_polling_state *na_polling_state;
+ /* we overwrite the hwna->na_vp pointer, so we save
+ * here its original value, to be restored at detach
+ */
+ struct netmap_vp_adapter *saved_na_vp;
};
+int nm_bdg_ctl_attach(struct nmreq_header *hdr, void *auth_token);
+int nm_bdg_ctl_detach(struct nmreq_header *hdr, void *auth_token);
+int nm_bdg_polling(struct nmreq_header *hdr);
int netmap_bwrap_attach(const char *name, struct netmap_adapter *);
-int netmap_vi_create(struct nmreq *, int);
+int netmap_vi_create(struct nmreq_header *hdr, int);
+int nm_vi_create(struct nmreq_header *);
+int nm_vi_destroy(const char *name);
+int netmap_bdg_list(struct nmreq_header *hdr);
#else /* !WITH_VALE */
-#define netmap_vi_create(nmr, a) (EOPNOTSUPP)
+#define netmap_vi_create(hdr, a) (EOPNOTSUPP)
#endif /* WITH_VALE */
#ifdef WITH_PIPES
@@ -1024,10 +1053,12 @@ int netmap_vi_create(struct nmreq *, int);
#define NM_MAXPIPES 64 /* max number of pipes per adapter */
struct netmap_pipe_adapter {
+ /* pipe identifier is up.name */
struct netmap_adapter up;
- u_int id; /* pipe identifier */
- int role; /* either NR_REG_PIPE_MASTER or NR_REG_PIPE_SLAVE */
+#define NM_PIPE_ROLE_MASTER 0x1
+#define NM_PIPE_ROLE_SLAVE 0x2
+ int role; /* either NM_PIPE_ROLE_MASTER or NM_PIPE_ROLE_SLAVE */
struct netmap_adapter *parent; /* adapter that owns the memory */
struct netmap_pipe_adapter *peer; /* the other end of the pipe */
@@ -1195,6 +1226,7 @@ int netmap_transmit(struct ifnet *, struct mbuf *);
struct netmap_slot *netmap_reset(struct netmap_adapter *na,
enum txrx tx, u_int n, u_int new_cur);
int netmap_ring_reinit(struct netmap_kring *);
+int netmap_rings_config_get(struct netmap_adapter *, struct nm_config_info *);
/* Return codes for netmap_*x_irq. */
enum {
@@ -1255,10 +1287,10 @@ static inline void
nm_update_hostrings_mode(struct netmap_adapter *na)
{
/* Process nr_mode and nr_pending_mode for host rings. */
- na->tx_rings[na->num_tx_rings].nr_mode =
- na->tx_rings[na->num_tx_rings].nr_pending_mode;
- na->rx_rings[na->num_rx_rings].nr_mode =
- na->rx_rings[na->num_rx_rings].nr_pending_mode;
+ na->tx_rings[na->num_tx_rings]->nr_mode =
+ na->tx_rings[na->num_tx_rings]->nr_pending_mode;
+ na->rx_rings[na->num_rx_rings]->nr_mode =
+ na->rx_rings[na->num_rx_rings]->nr_pending_mode;
}
/* set/clear native flags and if_transmit/netdev_ops */
@@ -1318,6 +1350,11 @@ nm_clear_native_flags(struct netmap_adapter *na)
#endif
}
+#ifdef linux
+int netmap_linux_config(struct netmap_adapter *na,
+ struct nm_config_info *info);
+#endif /* linux */
+
/*
* nm_*sync_prologue() functions are used in ioctl/poll and ptnetmap
* kthreads.
@@ -1373,9 +1410,10 @@ uint32_t nm_rxsync_prologue(struct netmap_kring *, struct netmap_ring *);
*/
int netmap_attach_common(struct netmap_adapter *);
/* fill priv->np_[tr]xq{first,last} using the ringid and flags information
- * coming from a struct nmreq
+ * coming from a struct nmreq_register
*/
-int netmap_interp_ringid(struct netmap_priv_d *priv, uint16_t ringid, uint32_t flags);
+int netmap_interp_ringid(struct netmap_priv_d *priv, uint32_t nr_mode,
+ uint16_t nr_ringid, uint64_t nr_flags);
/* update the ring parameters (number and size of tx and rx rings).
* It calls the nm_config callback, if available.
*/
@@ -1409,12 +1447,12 @@ void netmap_disable_all_rings(struct ifnet *);
void netmap_enable_all_rings(struct ifnet *);
int netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na,
- uint16_t ringid, uint32_t flags);
+ uint32_t nr_mode, uint16_t nr_ringid, uint64_t nr_flags);
void netmap_do_unregif(struct netmap_priv_d *priv);
u_int nm_bound_var(u_int *v, u_int dflt, u_int lo, u_int hi, const char *msg);
-int netmap_get_na(struct nmreq *nmr, struct netmap_adapter **na,
- struct ifnet **ifp, struct netmap_mem_d *nmd, int create);
+int netmap_get_na(struct nmreq_header *hdr, struct netmap_adapter **na,
+ struct ifnet **ifp, struct netmap_mem_d *nmd, int create);
void netmap_unget_na(struct netmap_adapter *na, struct ifnet *ifp);
int netmap_get_hw_na(struct ifnet *ifp,
struct netmap_mem_d *nmd, struct netmap_adapter **na);
@@ -1430,18 +1468,19 @@ int netmap_get_hw_na(struct ifnet *ifp,
* NM_BDG_MAXPORTS for broadcast, NM_BDG_MAXPORTS+1 to indicate
* drop.
*/
-typedef u_int (*bdg_lookup_fn_t)(struct nm_bdg_fwd *ft, uint8_t *ring_nr,
- struct netmap_vp_adapter *);
+typedef uint32_t (*bdg_lookup_fn_t)(struct nm_bdg_fwd *ft, uint8_t *ring_nr,
+ struct netmap_vp_adapter *, void *private_data);
typedef int (*bdg_config_fn_t)(struct nm_ifreq *);
typedef void (*bdg_dtor_fn_t)(const struct netmap_vp_adapter *);
+typedef void *(*bdg_update_private_data_fn_t)(void *private_data, void *callback_data, int *error);
struct netmap_bdg_ops {
bdg_lookup_fn_t lookup;
bdg_config_fn_t config;
bdg_dtor_fn_t dtor;
};
-u_int netmap_bdg_learning(struct nm_bdg_fwd *ft, uint8_t *dst_ring,
- struct netmap_vp_adapter *);
+uint32_t netmap_bdg_learning(struct nm_bdg_fwd *ft, uint8_t *dst_ring,
+ struct netmap_vp_adapter *, void *private_data);
#define NM_BRIDGES 8 /* number of bridges */
#define NM_BDG_MAXPORTS 254 /* up to 254 */
@@ -1449,45 +1488,47 @@ u_int netmap_bdg_learning(struct nm_bdg_fwd *ft, uint8_t *dst_ring,
#define NM_BDG_NOPORT (NM_BDG_MAXPORTS+1)
/* these are redefined in case of no VALE support */
-int netmap_get_bdg_na(struct nmreq *nmr, struct netmap_adapter **na,
+int netmap_get_bdg_na(struct nmreq_header *hdr, struct netmap_adapter **na,
struct netmap_mem_d *nmd, int create);
struct nm_bridge *netmap_init_bridges2(u_int);
void netmap_uninit_bridges2(struct nm_bridge *, u_int);
int netmap_init_bridges(void);
void netmap_uninit_bridges(void);
-int netmap_bdg_ctl(struct nmreq *nmr, struct netmap_bdg_ops *bdg_ops);
-int netmap_bdg_config(struct nmreq *nmr);
+int netmap_bdg_regops(const char *name, struct netmap_bdg_ops *bdg_ops, void *private_data, void *auth_token);
+int nm_bdg_update_private_data(const char *name, bdg_update_private_data_fn_t callback,
+ void *callback_data, void *auth_token);
+int netmap_bdg_config(struct nm_ifreq *nifr);
+void *netmap_bdg_create(const char *bdg_name, int *return_status);
+int netmap_bdg_destroy(const char *bdg_name, void *auth_token);
#else /* !WITH_VALE */
#define netmap_get_bdg_na(_1, _2, _3, _4) 0
#define netmap_init_bridges(_1) 0
#define netmap_uninit_bridges()
-#define netmap_bdg_ctl(_1, _2) EINVAL
+#define netmap_bdg_regops(_1, _2) EINVAL
#endif /* !WITH_VALE */
#ifdef WITH_PIPES
/* max number of pipes per device */
#define NM_MAXPIPES 64 /* XXX this should probably be a sysctl */
void netmap_pipe_dealloc(struct netmap_adapter *);
-int netmap_get_pipe_na(struct nmreq *nmr, struct netmap_adapter **na,
- struct netmap_mem_d *nmd, int create);
+int netmap_get_pipe_na(struct nmreq_header *hdr, struct netmap_adapter **na,
+ struct netmap_mem_d *nmd, int create);
#else /* !WITH_PIPES */
#define NM_MAXPIPES 0
#define netmap_pipe_alloc(_1, _2) 0
#define netmap_pipe_dealloc(_1)
-#define netmap_get_pipe_na(nmr, _2, _3, _4) \
- ({ int role__ = (nmr)->nr_flags & NR_REG_MASK; \
- (role__ == NR_REG_PIPE_MASTER || \
- role__ == NR_REG_PIPE_SLAVE) ? EOPNOTSUPP : 0; })
+#define netmap_get_pipe_na(hdr, _2, _3, _4) \
+ ((strchr(hdr->nr_name, '{') != NULL || strchr(hdr->nr_name, '}') != NULL) ? EOPNOTSUPP : 0)
#endif
#ifdef WITH_MONITOR
-int netmap_get_monitor_na(struct nmreq *nmr, struct netmap_adapter **na,
+int netmap_get_monitor_na(struct nmreq_header *hdr, struct netmap_adapter **na,
struct netmap_mem_d *nmd, int create);
void netmap_monitor_stop(struct netmap_adapter *na);
#else
-#define netmap_get_monitor_na(nmr, _2, _3, _4) \
- ((nmr)->nr_flags & (NR_MONITOR_TX | NR_MONITOR_RX) ? EOPNOTSUPP : 0)
+#define netmap_get_monitor_na(hdr, _2, _3, _4) \
+ (((struct nmreq_register *)hdr->nr_body)->nr_flags & (NR_MONITOR_TX | NR_MONITOR_RX) ? EOPNOTSUPP : 0)
#endif
#ifdef CONFIG_NET_NS
@@ -1508,7 +1549,11 @@ void netmap_fini(void);
int netmap_get_memory(struct netmap_priv_d* p);
void netmap_dtor(void *data);
-int netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread *);
+int netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data,
+ struct thread *, int nr_body_is_user);
+int netmap_ioctl_legacy(struct netmap_priv_d *priv, u_long cmd, caddr_t data,
+ struct thread *td);
+size_t nmreq_size_by_type(uint16_t nr_reqtype);
/* netmap_adapter creation/destruction */
@@ -1871,7 +1916,7 @@ static inline int nm_kring_pending(struct netmap_priv_d *np)
for_rx_tx(t) {
for (i = np->np_qfirst[t]; i < np->np_qlast[t]; i++) {
- struct netmap_kring *kring = &NMR(na, t)[i];
+ struct netmap_kring *kring = NMR(na, t)[i];
if (kring->nr_mode != kring->nr_pending_mode) {
return 1;
}
@@ -1980,7 +2025,7 @@ void nm_os_mitigation_cleanup(struct nm_generic_mit *mit);
struct nm_bdg_fwd { /* forwarding entry for a bridge */
void *ft_buf; /* netmap or indirect buffer */
uint8_t ft_frags; /* how many fragments (only on 1st frag) */
- uint8_t _ft_port; /* dst port (unused) */
+ uint16_t ft_offset; /* dst port (unused) */
uint16_t ft_flags; /* flags, e.g. indirect */
uint16_t ft_len; /* src fragment len */
uint16_t ft_next; /* next packet to same destination */
@@ -2094,7 +2139,6 @@ struct nm_kctx_cfg {
};
/* kthread configuration */
struct nm_kctx *nm_os_kctx_create(struct nm_kctx_cfg *cfg,
- unsigned int cfgtype,
void *opaque);
int nm_os_kctx_worker_start(struct nm_kctx *);
void nm_os_kctx_worker_stop(struct nm_kctx *);
@@ -2120,19 +2164,21 @@ struct netmap_pt_host_adapter {
int (*parent_nm_notify)(struct netmap_kring *kring, int flags);
void *ptns;
};
-/* ptnetmap HOST routines */
-int netmap_get_pt_host_na(struct nmreq *nmr, struct netmap_adapter **na,
- struct netmap_mem_d * nmd, int create);
-int ptnetmap_ctl(struct nmreq *nmr, struct netmap_adapter *na);
+
+/* ptnetmap host-side routines */
+int netmap_get_pt_host_na(struct nmreq_header *hdr, struct netmap_adapter **na,
+ struct netmap_mem_d * nmd, int create);
+int ptnetmap_ctl(const char *nr_name, int create, struct netmap_adapter *na);
+
static inline int
nm_ptnetmap_host_on(struct netmap_adapter *na)
{
return na && na->na_flags & NAF_PTNETMAP_HOST;
}
#else /* !WITH_PTNETMAP_HOST */
-#define netmap_get_pt_host_na(nmr, _2, _3, _4) \
- ((nmr)->nr_flags & (NR_PTNETMAP_HOST) ? EOPNOTSUPP : 0)
-#define ptnetmap_ctl(_1, _2) EINVAL
+#define netmap_get_pt_host_na(hdr, _2, _3, _4) \
+ (((struct nmreq_register *)hdr->nr_body)->nr_flags & (NR_PTNETMAP_HOST) ? EOPNOTSUPP : 0)
+#define ptnetmap_ctl(_1, _2, _3) EINVAL
#define nm_ptnetmap_host_on(_1) EINVAL
#endif /* !WITH_PTNETMAP_HOST */
@@ -2175,4 +2221,7 @@ void ptnet_nm_krings_delete(struct netmap_adapter *na);
void ptnet_nm_dtor(struct netmap_adapter *na);
#endif /* WITH_PTNETMAP_GUEST */
+struct nmreq_option * nmreq_findoption(struct nmreq_option *, uint16_t);
+int nmreq_checkduplicate(struct nmreq_option *);
+
#endif /* _NET_NETMAP_KERN_H_ */