TAS
TCP Acceleration as an OS Service
network.h
1 /*
2  * Copyright 2019 University of Washington, Max Planck Institute for
3  * Software Systems, and The University of Texas at Austin
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #ifndef NETWORK_H_
26 #define NETWORK_H_
27 
28 #include <rte_config.h>
29 #include <rte_memcpy.h>
30 #include <rte_ether.h>
31 #include <rte_ethdev.h>
32 #include <rte_mbuf.h>
33 #include <rte_ip.h>
34 
35 #include <fastpath.h>
36 
37 struct network_buf_handle;
38 
39 extern uint8_t net_port_id;
40 extern uint16_t rss_reta_size;
41 
42 int network_thread_init(struct dataplane_context *ctx);
43 int network_rx_interrupt_ctl(struct network_thread *t, int turnon);
44 
45 int network_scale_up(uint16_t old, uint16_t new);
46 int network_scale_down(uint16_t old, uint16_t new);
47 
48 
49 static inline void network_buf_reset(struct network_buf_handle *bh)
50 {
51  struct rte_mbuf *mb = (struct rte_mbuf *) bh;
52  mb->ol_flags = 0;
53 }
54 
55 static inline uint16_t network_buf_off(struct network_buf_handle *bh)
56 {
57  return ((struct rte_mbuf *) bh)->data_off;
58 }
59 
60 static inline uint16_t network_buf_len(struct network_buf_handle *bh)
61 {
62  return ((struct rte_mbuf *) bh)->data_len;
63 }
64 
65 static inline void *network_buf_buf(struct network_buf_handle *bh)
66 {
67  return ((struct rte_mbuf *) bh)->buf_addr;
68 }
69 
70 static inline void *network_buf_bufoff(struct network_buf_handle *bh)
71 {
72  struct rte_mbuf *mb = (struct rte_mbuf *) bh;
73  return mb->buf_addr + mb->data_off;
74 }
75 
76 static inline void network_buf_setoff(struct network_buf_handle *bh,
77  uint16_t off)
78 {
79  ((struct rte_mbuf *) bh)->data_off = off;
80 }
81 
82 static inline void network_buf_setlen(struct network_buf_handle *bh,
83  uint16_t len)
84 {
85  struct rte_mbuf *mb = (struct rte_mbuf *) bh;
86  mb->pkt_len = mb->data_len = len;
87 }
88 
89 
90 static inline int network_poll(struct network_thread *t, unsigned num,
91  struct network_buf_handle **bhs)
92 {
93  struct rte_mbuf **mbs = (struct rte_mbuf **) bhs;
94 
95  num = rte_eth_rx_burst(net_port_id, t->queue_id, mbs, num);
96  if (num == 0) {
97  return 0;
98  }
99 
100 #ifdef FLEXNIC_TRACE_TX
101  unsigned i;
102  for (i = 0; i < num; i++) {
103  trace_event(FLEXNIC_TRACE_EV_RXPKT, network_buf_len(bhs[i]),
104  network_buf_bufoff(bhs[i]));
105  }
106 #endif
107 
108  return num;
109 }
110 
111 static inline int network_send(struct network_thread *t, unsigned num,
112  struct network_buf_handle **bhs)
113 {
114  struct rte_mbuf **mbs = (struct rte_mbuf **) bhs;
115 
116 #ifdef FLEXNIC_TRACE_TX
117  unsigned i;
118  for (i = 0; i < num; i++) {
119  trace_event(FLEXNIC_TRACE_EV_TXPKT, network_buf_len(bhs[i]),
120  network_buf_bufoff(bhs[i]));
121  }
122 #endif
123 
124  return rte_eth_tx_burst(net_port_id, t->queue_id, mbs, num);
125 }
126 
127 
128 static inline int network_buf_alloc(struct network_thread *t, unsigned num,
129  struct network_buf_handle **bhs)
130 {
131  struct rte_mbuf **mbs = (struct rte_mbuf **) bhs;
132  unsigned i;
133 
134  /* try bulk alloc first. if it fails try individual mbufs */
135  if (rte_pktmbuf_alloc_bulk(t->pool, mbs, num) == 0) {
136  return num;
137  }
138 
139  for (i = 0; i < num; i++) {
140  if ((mbs[i] = rte_pktmbuf_alloc(t->pool)) == NULL) {
141  break;
142  }
143  }
144 
145  return i;
146 }
147 
148 static inline void network_free(unsigned num, struct network_buf_handle **bufs)
149 {
150  unsigned i;
151  for (i = 0; i < num; i++) {
152  rte_pktmbuf_free_seg((struct rte_mbuf *) bufs[i]);
153  }
154 }
155 
157 static inline uint16_t network_ip_phdr_xsum(beui32_t ip_src, beui32_t ip_dst,
158  uint8_t proto, uint16_t l3_paylen)
159 {
160  uint32_t sum = 0;
161 
162  sum += ip_src.x & 0xffff;
163  sum += (ip_src.x >> 16) & 0xffff;
164  sum += ip_dst.x & 0xffff;
165  sum += (ip_dst .x >> 16) & 0xffff;
166  sum += ((uint16_t) proto) << 8;
167  sum += t_beui16(l3_paylen).x;
168 
169  sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff);
170  sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff);
171 
172  return (uint16_t) sum;
173 }
174 
175 static inline uint16_t network_buf_tcpxsums(struct network_buf_handle *bh, uint8_t l2l,
176  uint8_t l3l, void *ip_hdr, beui32_t ip_s, beui32_t ip_d, uint8_t ip_proto,
177  uint16_t l3_paylen)
178 {
179  struct rte_mbuf * restrict mb = (struct rte_mbuf *) bh;
180  mb->tx_offload = l2l | ((uint32_t) l3l << 7);
181  /*mb->l2_len = l2l;
182  mb->l3_len = l3l;
183  mb->l4_len = 0;*/
184  mb->ol_flags = PKT_TX_IPV4 | PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM;
185 
186  return network_ip_phdr_xsum(ip_s, ip_d, ip_proto, l3_paylen);
187 }
188 
189 static inline int network_buf_flowgroup(struct network_buf_handle *bh,
190  uint16_t *fg)
191 {
192  struct rte_mbuf *mb = (struct rte_mbuf *) bh;
193  if (!(mb->ol_flags & PKT_RX_RSS_HASH)) {
194  *fg = 0;
195  return 0;
196  }
197 
198  *fg = mb->hash.rss & (rss_reta_size - 1);
199  return 0;
200 }
201 
202 #endif /* ndef NETWORK_H_ */
Definition: utils.h:45