diff options
| author | Vincenzo Maffione <vmaffione@FreeBSD.org> | 2018-04-12 07:20:50 +0000 |
|---|---|---|
| committer | Vincenzo Maffione <vmaffione@FreeBSD.org> | 2018-04-12 07:20:50 +0000 |
| commit | 2ff91c175eca50b7d0d9da6b31eae4109c034137 (patch) | |
| tree | 15a4f8847a8cabd782f67326125c48fed4fdd27b /sys/dev/netmap/netmap_kern.h | |
| parent | 66def52613043a86172a2ebe6feab214258fa2fa (diff) | |
Notes
Diffstat (limited to 'sys/dev/netmap/netmap_kern.h')
| -rw-r--r-- | sys/dev/netmap/netmap_kern.h | 155 |
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_ */ |
