Advertisement
Guest User

Untitled

a guest
May 28th, 2016
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.80 KB | None | 0 0
  1. extern crate netmap_sys;
  2.  
  3. use ::libc;
  4. use std::mem;
  5. use std::ptr;
  6. use std::slice;
  7. use std::iter::Iterator;
  8. use std::ffi::{CStr,CString};
  9. use self::netmap_sys::netmap;
  10. use self::netmap_sys::netmap_user;
  11.  
  12. /// Forward slot
  13. pub use self::netmap_sys::netmap::NS_FORWARD;
  14.  
  15. /// Indicate that buffer was changed
  16. pub use self::netmap_sys::netmap::NS_BUF_CHANGED;
  17.  
  18. /// Report when sent
  19. pub use self::netmap_sys::netmap::NS_REPORT;
  20.  
  21. /// Enable forwarding on ring
  22. pub use self::netmap_sys::netmap::NR_FORWARD;
  23.  
  24. #[derive(Debug)]
  25. #[allow(dead_code)]
  26. pub enum Direction {
  27. Input,
  28. Output,
  29. InputOutput
  30. }
  31.  
  32. #[derive(Debug)]
  33. pub struct NetmapError {
  34. msg: String,
  35. }
  36.  
  37. impl NetmapError {
  38. fn new(msg: String) -> Self {
  39. NetmapError { msg: msg }
  40. }
  41. }
  42.  
  43. pub trait NetmapSlot {
  44. fn get_len(&self) -> u16;
  45. fn get_flags(&self) -> u16;
  46. fn set_flags(&mut self, flag: u16);
  47. fn get_buf_idx(&self) -> u32;
  48. fn set_buf_idx(&mut self, idx: u32);
  49. }
  50.  
  51. pub struct RxSlot(netmap::netmap_slot);
  52.  
  53. impl NetmapSlot for RxSlot {
  54. fn get_len(&self) -> u16 {
  55. self.0.len
  56. }
  57.  
  58. fn set_flags(&mut self, flag: u16) {
  59. self.0.flags |= flag;
  60. }
  61.  
  62. fn get_flags(&self) -> u16 {
  63. self.0.flags
  64. }
  65.  
  66. fn get_buf_idx(&self) -> u32 {
  67. self.0.buf_idx
  68. }
  69.  
  70. fn set_buf_idx(&mut self, idx: u32) {
  71. self.0.buf_idx = idx
  72. }
  73. }
  74.  
  75. impl RxSlot {
  76. #[inline]
  77. pub fn get_buf<'b,'a>(&'a self, ring: &RxRing) -> &'b [u8] {
  78. let buf_idx = self.0.buf_idx;
  79. let buf = unsafe { netmap_user::NETMAP_BUF(mem::transmute(ring), buf_idx as isize) as *const u8 };
  80. unsafe { slice::from_raw_parts::<u8>(buf, self.0.len as usize) }
  81. }
  82. }
  83.  
  84. pub struct TxSlot(netmap::netmap_slot);
  85.  
  86. impl NetmapSlot for TxSlot {
  87. #[inline]
  88. fn get_len(&self) -> u16 {
  89. self.0.len
  90. }
  91.  
  92. #[inline]
  93. fn set_flags(&mut self, flag: u16) {
  94. self.0.flags |= flag;
  95. }
  96.  
  97. #[inline]
  98. fn get_flags(&self) -> u16 {
  99. self.0.flags
  100. }
  101.  
  102. #[inline]
  103. fn get_buf_idx(&self) -> u32 {
  104. self.0.buf_idx
  105. }
  106.  
  107. #[inline]
  108. fn set_buf_idx(&mut self, idx: u32) {
  109. self.0.buf_idx = idx
  110. }
  111. }
  112.  
  113. impl TxSlot {
  114. #[inline]
  115. pub fn get_buf_mut<'b,'a>(&'a mut self, ring: &TxRing) -> &'b mut [u8] {
  116. let buf_idx = self.0.buf_idx;
  117. let buf = unsafe { netmap_user::NETMAP_BUF(mem::transmute(ring), buf_idx as isize) as *mut u8 };
  118. unsafe { slice::from_raw_parts_mut::<u8>(buf, self.0.len as usize) }
  119. }
  120.  
  121. #[inline]
  122. pub fn set_len(&mut self, len: u16) {
  123. self.0.len = len;
  124. }
  125. }
  126.  
  127. pub trait NetmapRing {
  128. fn id(&self) -> u16;
  129. fn is_empty(&self) -> bool;
  130. fn next_slot(&mut self);
  131. fn set_flags(&mut self, flag: u32);
  132. }
  133.  
  134. pub struct RxRing(netmap::netmap_ring);
  135.  
  136. impl RxRing {
  137. #[allow(dead_code)]
  138. #[inline]
  139. pub fn get_slot_mut<'a,'b>(&'a self) -> &'b mut RxSlot {
  140. let cur = self.0.cur;
  141. let slots = &self.0.slot as *const netmap::netmap_slot;
  142. unsafe { mem::transmute(slots.offset(cur as isize)) }
  143. }
  144.  
  145. #[inline]
  146. pub fn iter(&mut self) -> RxSlotIter {
  147. let cur = self.0.cur;
  148. RxSlotIter {
  149. ring: self,
  150. cur: cur,
  151. }
  152. }
  153. }
  154.  
  155. impl NetmapRing for RxRing {
  156. #[inline]
  157. fn id(&self) -> u16 {
  158. self.0.ringid
  159. }
  160.  
  161. #[inline]
  162. fn is_empty(&self) -> bool {
  163. self.0.cur == self.0.tail
  164. }
  165.  
  166. #[inline]
  167. fn set_flags(&mut self, flag: u32) {
  168. self.0.flags |= flag;
  169. }
  170.  
  171. #[inline]
  172. fn next_slot(&mut self) {
  173. self.0.cur = if self.0.cur + 1 == self.0.num_slots { 0 } else { self.0.cur + 1 };
  174. self.0.head = self.0.cur;
  175. }
  176. }
  177.  
  178. pub struct RxSlotIter<'a> {
  179. ring: &'a mut RxRing,
  180. cur: u32,
  181. }
  182.  
  183. impl<'a> Iterator for RxSlotIter<'a> {
  184. type Item = (&'a mut RxSlot, &'a [u8]);
  185.  
  186. #[inline]
  187. fn next(&mut self) -> Option<Self::Item> {
  188. self.ring.0.cur = self.cur;
  189. self.ring.0.head = self.ring.0.cur;
  190.  
  191. if self.ring.is_empty() {
  192. return None;
  193. }
  194. let cur = self.cur;
  195. let slots = self.ring.0.slot.as_mut_ptr();
  196. let slot: &mut RxSlot = unsafe { mem::transmute(slots.offset(cur as isize)) };
  197. let buf = slot.get_buf(self.ring);
  198. self.cur = if self.cur + 1 == self.ring.0.num_slots { 0 } else { self.cur + 1 };
  199. Some((slot, buf))
  200. }
  201. }
  202.  
  203. impl<'a> Drop for RxSlotIter<'a> {
  204. fn drop(&mut self) {
  205. self.ring.0.cur = self.cur;
  206. self.ring.0.head = self.ring.0.cur;
  207. }
  208. }
  209.  
  210. pub struct RxRingIter<'d> {
  211. cur: u16,
  212. last: u16,
  213. netmap: &'d NetmapDescriptor,
  214. }
  215.  
  216. impl<'d> Iterator for RxRingIter<'d> {
  217. type Item = &'d mut RxRing;
  218.  
  219. #[inline]
  220. fn next<'a>(&'a mut self) -> Option<&'d mut RxRing> {
  221. if self.cur > self.last {
  222. return None;
  223. }
  224. let rx_ring = {
  225. let cur = self.cur.clone();
  226. self.netmap.get_rx_ring(cur)
  227. };
  228. self.cur += 1;
  229. Some(rx_ring)
  230. }
  231. }
  232.  
  233. pub struct TxRing(netmap::netmap_ring);
  234.  
  235. impl TxRing {
  236. #[inline]
  237. pub fn get_slot_mut<'a,'b>(&'a self) -> &'b mut TxSlot {
  238. let cur = self.0.cur;
  239. let slots = &self.0.slot as *const netmap::netmap_slot;
  240. unsafe { mem::transmute(slots.offset(cur as isize)) }
  241. }
  242.  
  243. #[inline]
  244. pub fn iter(&mut self) -> TxSlotIter {
  245. let cur = self.0.cur;
  246. TxSlotIter {
  247. ring: self,
  248. cur: cur,
  249. }
  250. }
  251. }
  252.  
  253. impl NetmapRing for TxRing {
  254. #[inline]
  255. fn id(&self) -> u16 {
  256. self.0.ringid
  257. }
  258.  
  259. #[inline]
  260. fn is_empty(&self) -> bool {
  261. self.0.cur == self.0.tail
  262. }
  263.  
  264. #[inline]
  265. fn set_flags(&mut self, flag: u32) {
  266. self.0.flags |= flag;
  267. }
  268.  
  269. #[inline]
  270. fn next_slot(&mut self) {
  271. self.0.cur = if self.0.cur + 1 == self.0.num_slots { 0 } else { self.0.cur + 1 };
  272. self.0.head = self.0.cur;
  273. }
  274. }
  275.  
  276. impl<'a> Iterator for &'a mut TxRing {
  277. type Item = &'a mut TxSlot;
  278.  
  279. #[inline]
  280. fn next(&mut self) -> Option<Self::Item> {
  281. let cur = self.0.cur;
  282. let slots = &self.0.slot as *const netmap::netmap_slot;
  283. let slot = unsafe { mem::transmute(slots.offset(cur as isize)) };
  284. self.next_slot();
  285. slot
  286. }
  287. }
  288.  
  289. pub struct TxRingIter<'d> {
  290. last: u16,
  291. cur: u16,
  292. netmap: &'d NetmapDescriptor,
  293. }
  294.  
  295. impl<'d> Iterator for TxRingIter<'d> {
  296. type Item = &'d mut TxRing;
  297.  
  298. #[inline]
  299. fn next<'a>(&'a mut self) -> Option<&'d mut TxRing> {
  300. if self.cur > self.last {
  301. return None;
  302. }
  303. let tx_ring = {
  304. let cur = self.cur.clone();
  305. self.netmap.get_tx_ring(cur)
  306. };
  307. self.cur += 1;
  308. Some(tx_ring)
  309. }
  310. }
  311.  
  312. /// Slot and buffer iterator
  313. pub struct TxSlotIter<'a> {
  314. ring: &'a mut TxRing,
  315. cur: u32
  316. }
  317.  
  318. impl<'a> Iterator for TxSlotIter<'a> {
  319. type Item = (&'a mut TxSlot, &'a mut [u8]);
  320.  
  321. #[inline]
  322. fn next(&mut self) -> Option<Self::Item> {
  323. self.ring.0.cur = self.cur;
  324. self.ring.0.head = self.ring.0.cur;
  325.  
  326. if self.ring.is_empty() {
  327. return None;
  328. }
  329. let cur = self.cur;
  330. let slots = self.ring.0.slot.as_mut_ptr();
  331. let slot: &mut TxSlot = unsafe { mem::transmute(slots.offset(cur as isize)) };
  332. slot.set_len(2048);
  333. let buf = slot.get_buf_mut(self.ring);
  334. self.cur = if self.cur + 1 == self.ring.0.num_slots { 0 } else { self.cur + 1 };
  335. Some((slot, buf))
  336. }
  337. }
  338.  
  339. impl<'a> Drop for TxSlotIter<'a> {
  340. fn drop(&mut self) {
  341. self.ring.0.cur = self.cur;
  342. self.ring.0.head = self.ring.0.cur;
  343. }
  344. }
  345.  
  346. /// Netmap descriptor wrapper
  347. pub struct NetmapDescriptor {
  348. raw: *mut netmap_user::nm_desc
  349. }
  350.  
  351. unsafe impl Send for NetmapDescriptor {}
  352.  
  353. impl NetmapDescriptor {
  354. pub fn new(iface: &str) -> Result<Self, NetmapError> {
  355. let base_nmd: netmap::nmreq = unsafe { mem::zeroed() };
  356. let netmap_iface = CString::new(format!("netmap:{}", iface)).unwrap();
  357.  
  358. let netmap_desc = unsafe { netmap_user::nm_open(netmap_iface.as_ptr(), &base_nmd, 0, ptr::null()) };
  359. if netmap_desc == ptr::null_mut() {
  360. return Err(NetmapError::new(format!("Can't open {:?}", netmap_iface)));
  361. }
  362. Ok(NetmapDescriptor {
  363. raw: netmap_desc
  364. })
  365. }
  366.  
  367. pub fn new_with_memory(iface: &str, parent: &NetmapDescriptor) -> Result<Self, NetmapError> {
  368. let base_nmd: netmap::nmreq = unsafe { mem::zeroed() };
  369. let netmap_iface = CString::new(format!("netmap:{}", iface)).unwrap();
  370.  
  371. let netmap_desc = unsafe { netmap_user::nm_open(netmap_iface.as_ptr(), &base_nmd, netmap_user::NM_OPEN_NO_MMAP as u64, parent.raw) };
  372. if netmap_desc == ptr::null_mut() {
  373. return Err(NetmapError::new(format!("Can't open {:?}", netmap_iface)));
  374. }
  375. Ok(NetmapDescriptor {
  376. raw: netmap_desc
  377. })
  378. }
  379.  
  380. pub fn rx_iter<'i, 'd: 'i>(&'d mut self) -> RxRingIter<'i> {
  381. let (first, last) = self.get_rx_rings();
  382.  
  383. RxRingIter {
  384. last: last,
  385. cur: first,
  386. netmap: self,
  387. }
  388. }
  389.  
  390. pub fn tx_iter<'i, 'd: 'i>(&'d mut self) -> TxRingIter<'i> {
  391. let (first, last) = self.get_tx_rings();
  392.  
  393. TxRingIter {
  394. last: last,
  395. cur: first,
  396. netmap: self,
  397. }
  398. }
  399.  
  400. pub fn clone_ring(&self, ring: u16, dir: Direction) -> Result<Self,NetmapError> {
  401. let mut nm_desc_raw: netmap_user::nm_desc = unsafe { (*(self.raw)) };
  402.  
  403. /* XXX: check that we opened it with ALL_NIC before */
  404. let (flag, ring_flag) = match dir {
  405. Direction::Input => (netmap::NR_RX_RINGS_ONLY, netmap::NETMAP_NO_TX_POLL),
  406. Direction::Output => (netmap::NR_TX_RINGS_ONLY, 0),
  407. Direction::InputOutput => (0, 0),
  408. };
  409. nm_desc_raw.req.nr_flags = netmap::NR_REG_ONE_NIC as u32 | flag as u32;
  410. if ring == self.get_rx_rings_count() { nm_desc_raw.req.nr_flags = netmap::NR_REG_SW as u32 | flag };
  411. nm_desc_raw.req.nr_ringid = ring | ring_flag as u16;
  412. nm_desc_raw.self_ = &mut nm_desc_raw;
  413.  
  414. let ifname = unsafe { CStr::from_ptr(nm_desc_raw.req.nr_name.as_ptr()).to_str().unwrap() };
  415. let netmap_ifname = CString::new(format!("netmap:{}", ifname)).unwrap();
  416.  
  417. let netmap_desc = unsafe {
  418. netmap_user::nm_open(netmap_ifname.as_ptr(),
  419. ptr::null(),
  420. netmap_user::NM_OPEN_NO_MMAP as u64 | netmap_user::NM_OPEN_IFNAME as u64 /* | flag as u64 */,
  421. &mut nm_desc_raw)
  422. };
  423. if netmap_desc == ptr::null_mut() {
  424. return Err(NetmapError::new(format!("Can't open ring {}", ring)));
  425. }
  426. Ok(NetmapDescriptor {
  427. raw: netmap_desc
  428. })
  429. }
  430.  
  431. pub fn get_rx_rings_count(&self) -> u16 {
  432. let nifp = unsafe { (*self.raw).nifp };
  433. unsafe { (*nifp).ni_rx_rings as u16 }
  434. }
  435.  
  436. pub fn get_tx_rings_count(&self) -> u16 {
  437. let nifp = unsafe { (*self.raw).nifp };
  438. unsafe { (*nifp).ni_tx_rings as u16 }
  439. }
  440.  
  441. #[allow(dead_code)]
  442. pub fn get_flags(&self) -> u32 {
  443. unsafe { (*self.raw).req.nr_flags }
  444. }
  445.  
  446. pub fn get_rx_rings(&self) -> (u16,u16) {
  447. unsafe { ((*self.raw).first_rx_ring, (*self.raw).last_rx_ring) }
  448. }
  449.  
  450. pub fn get_tx_rings(&self) -> (u16,u16) {
  451. unsafe { ((*self.raw).first_tx_ring, (*self.raw).last_tx_ring) }
  452. }
  453.  
  454. #[inline]
  455. fn get_tx_ring(&self, ring: u16) -> &mut TxRing {
  456. let nifp = unsafe { (*self.raw).nifp };
  457.  
  458. unsafe { mem::transmute(netmap_user::NETMAP_TXRING(nifp, ring as isize)) }
  459. }
  460.  
  461. #[inline]
  462. fn get_rx_ring(&self, ring: u16) -> &mut RxRing {
  463. let nifp = unsafe { (*self.raw).nifp };
  464.  
  465. unsafe { mem::transmute(netmap_user::NETMAP_RXRING(nifp, ring as isize)) }
  466. }
  467.  
  468. #[allow(dead_code)]
  469. fn find_free_tx_ring(&self) -> Option<&mut TxRing> {
  470. let (first, last) = self.get_tx_rings();
  471.  
  472. for ring in first..last+1 {
  473. let tx_ring = self.get_tx_ring(ring);
  474. if !tx_ring.is_empty() {
  475. return Some(tx_ring);
  476. }
  477. }
  478. return None;
  479. }
  480.  
  481. #[allow(dead_code)]
  482. pub fn get_fd(&self) -> i32 {
  483. unsafe { (*self.raw).fd }
  484. }
  485.  
  486. pub fn poll(&mut self, dir: Direction) -> Option<()> {
  487. let fd = unsafe { (*self.raw).fd };
  488. let mut pollfd: libc::pollfd = unsafe { mem::zeroed() };
  489.  
  490. pollfd.fd = fd;
  491. pollfd.events = match dir {
  492. Direction::Input => libc::POLLIN,
  493. Direction::Output => libc::POLLOUT,
  494. Direction::InputOutput => libc::POLLIN | libc::POLLOUT,
  495. };
  496.  
  497. let rv = unsafe { libc::poll(&mut pollfd, 1, 1000) };
  498. if rv <= 0 {
  499. return None;
  500. }
  501. if pollfd.revents & libc::POLLERR == libc::POLLERR {
  502. println!("POLLERR!");
  503. return None;
  504. }
  505. Some(())
  506. }
  507. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement