xref: /mOS-networking-stack/core/src/eth_out.c (revision dcdbbb98)
1 #include <stdio.h>
2 
3 #include <stdint.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <assert.h>
7 
8 #ifdef DARWIN
9 #include <netinet/if_ether.h>
10 #include <netinet/tcp.h>
11 #else
12 #include <linux/if_ether.h>
13 #include <linux/tcp.h>
14 #endif
15 #include <string.h>
16 #include <netinet/ip.h>
17 
18 #include "mtcp.h"
19 #include "arp.h"
20 #include "eth_out.h"
21 #include "debug.h"
22 #include "mos_api.h"
23 #include "config.h"
24 
25 #ifndef TRUE
26 #define TRUE (1)
27 #endif
28 
29 #ifndef FALSE
30 #define FALSE (0)
31 #endif
32 
33 #ifndef ERROR
34 #define ERROR (-1)
35 #endif
36 
37 #define MAX(a, b) ((a)>(b)?(a):(b))
38 #define MIN(a, b) ((a)<(b)?(a):(b))
39 
40 #define MAX_WINDOW_SIZE 65535
41 
42 /*----------------------------------------------------------------------------*/
43 enum ETH_BUFFER_RETURN {BUF_RET_MAYBE, BUF_RET_ALWAYS};
44 /*----------------------------------------------------------------------------*/
45 int
46 FlushSendChunkBuf(mtcp_manager_t mtcp, int nif)
47 {
48 	return 0;
49 }
50 /*----------------------------------------------------------------------------*/
51 inline void
52 FillOutPacketEthContext(struct pkt_ctx *pctx, uint32_t cur_ts, int out_ifidx,
53 						struct ethhdr *ethh, int eth_len)
54 {
55 	pctx->p.cur_ts = cur_ts;
56 	pctx->p.in_ifidx = -1;
57 	pctx->out_ifidx = out_ifidx;
58 	pctx->p.ethh = ethh;
59 	pctx->p.eth_len = eth_len;
60 }
61 /*----------------------------------------------------------------------------*/
62 uint8_t *
63 EthernetOutput(struct mtcp_manager *mtcp, struct pkt_ctx *pctx,
64 		uint16_t h_proto, int nif, unsigned char* dst_haddr, uint16_t iplen,
65 		uint32_t cur_ts)
66 {
67 	uint8_t *buf;
68 	struct ethhdr *ethh;
69 	int i;
70 
71 	/*
72  	 * -sanity check-
73 	 * return early if no interface is set (if routing entry does not exist)
74 	 */
75 	if (nif < 0) {
76 		TRACE_INFO("No interface set!\n");
77 		return NULL;
78 	}
79 
80 	if (!mtcp->iom->get_wptr) {
81 		TRACE_INFO("get_wptr() in io_module is undefined.");
82 		return NULL;
83 	}
84 	buf = mtcp->iom->get_wptr(mtcp->ctx, nif, iplen + ETHERNET_HEADER_LEN);
85 	if (!buf) {
86 		TRACE_DBG("Failed to get available write buffer\n");
87 		return NULL;
88 	}
89 
90 	ethh = (struct ethhdr *)buf;
91 	for (i = 0; i < ETH_ALEN; i++) {
92 		ethh->h_source[i] = g_config.mos->netdev_table->ent[nif]->haddr[i];
93 		ethh->h_dest[i] = dst_haddr[i];
94 	}
95 	ethh->h_proto = htons(h_proto);
96 
97 	if (pctx)
98 		FillOutPacketEthContext(pctx, cur_ts, nif,
99 					ethh, iplen + ETHERNET_HEADER_LEN);
100 
101 	return (uint8_t *)(ethh + 1);
102 }
103 /*----------------------------------------------------------------------------*/
104 void
105 ForwardEthernetFrame(struct mtcp_manager *mtcp, struct pkt_ctx *pctx)
106 {
107 	uint8_t *buf;
108 
109 	if (g_config.mos->nic_forward_table != NULL) {
110 		pctx->out_ifidx =
111 			g_config.mos->nic_forward_table->nic_fwd_table[pctx->p.in_ifidx];
112 
113 		if (pctx->out_ifidx == -1) {
114 			TRACE_DBG("Could not find outgoing index (index)!\n");
115 			return;
116 		}
117 
118 		if (!mtcp->iom->get_wptr) {
119 			TRACE_INFO("get_wptr() in io_module is undefined.");
120 			return;
121 		}
122 
123 		buf = mtcp->iom->get_wptr(mtcp->ctx, pctx->out_ifidx, pctx->p.eth_len);
124 
125 		if (!buf) {
126 			TRACE_DBG("Failed to get available write buffer\n");
127 			return;
128 		}
129 
130 		memcpy(buf, pctx->p.ethh, pctx->p.eth_len);
131 	} else {
132 		TRACE_DBG("Ethernet forwarding table entry does not exist.\n");
133 	}
134 }
135 /*----------------------------------------------------------------------------*/
136