Skip to content

Commit 8a6b6f5

Browse files
committed
net: rtl and e1000 can reply to ARP
1 parent 6366faf commit 8a6b6f5

File tree

8 files changed

+93
-40
lines changed

8 files changed

+93
-40
lines changed

include/ng/net.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ struct net_if {
1717
struct net_if_vtbl *vtbl;
1818
};
1919

20+
#define NET_SEND(nif, pk) (nif)->vtbl->send(nif, pk)
21+
2022
uint16_t net_checksum_add(uint16_t *addr, int count, uint16_t sum);
2123
uint16_t net_checksum_finish(uint16_t sum);
2224
uint16_t net_checksum_begin(uint16_t *addr, int count);
2325
uint16_t net_checksum(uint16_t *addr, int count);
2426

25-
void print_ip4_addr(struct in_addr *);
26-
void print_ip6_addr(struct in6_addr *);
27-
void print_ip6_addr_abbrev(struct in6_addr *);
27+
void net_ingress(struct pk *pk);
28+
29+
void net_worker();

kernel/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ add_executable(nightingale_kernel
8787
net/ip_ingress.c
8888
net/arp.c
8989
net/net_ingress.c
90+
net/worker.c
91+
net/ip_egress.c
9092
)
9193

9294
if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "X86_64")

kernel/drv/e1000.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ static void e1000_reset(struct e1000 *e) {
166166

167167
w32(IMC, INT_ALL);
168168

169-
__atomic_thread_fence(__ATOMIC_SEQ_CST);
169+
__atomic_thread_fence(memory_order_seq_cst);
170170
}
171171

172172
static uint16_t e1000_eeprom_read(struct e1000 *e, uint8_t addr) {
@@ -265,8 +265,7 @@ static void e1000_log_link_status(struct e1000 *e) {
265265
}
266266

267267
static void e1000_send(struct e1000 *e, void *data, size_t len) {
268-
int i = 0;
269-
uint32_t tail = e->tx;
268+
int tail = e->tx;
270269

271270
struct e1000_tx_desc *desc = &e->tx_descs[tail];
272271
memcpy(e->tx_buffer + tail * TX_BUFFER_SIZE, data, len);
@@ -277,17 +276,15 @@ static void e1000_send(struct e1000 *e, void *data, size_t len) {
277276

278277
printf("e1000: sending %zu bytes, tail is now %u\n", len, tail);
279278

280-
__atomic_thread_fence(__ATOMIC_RELEASE);
279+
__atomic_thread_fence(memory_order_release);
281280

282281
e->tx = tail;
283282
w32(TDT, tail);
284283
}
285284

286-
void net_ingress(struct pk *pk);
287-
288285
static void e1000_receive(struct e1000 *e) {
289-
uint32_t head = r32(RDH);
290-
uint32_t tail = e->rx;
286+
int head = r32(RDH);
287+
int tail = e->rx;
291288

292289
while (head != tail) {
293290
printf("head: %u, tail: %u\n", head, tail);
@@ -297,14 +294,19 @@ static void e1000_receive(struct e1000 *e) {
297294
break;
298295

299296
void *data = e->rx_buffer + tail * RX_BUFFER_SIZE;
297+
298+
// TODO: don't call ingress in the interrupt,
299+
// this has to go to a queue.
300300
struct pk *pk = pk_alloc();
301301
pk->len = desc->length;
302+
pk->origin_if = &e->nif;
302303
memcpy(pk->data, data, desc->length);
303304
net_ingress(pk);
304305

305306
desc->status = 0;
307+
desc->length = RX_BUFFER_SIZE;
306308

307-
__atomic_thread_fence(__ATOMIC_RELEASE);
309+
__atomic_thread_fence(memory_order_release);
308310

309311
w32(RDT, tail);
310312

@@ -313,7 +315,12 @@ static void e1000_receive(struct e1000 *e) {
313315
}
314316
}
315317

316-
static void e1000_init(struct e1000 *e) {
318+
static struct net_if_vtbl net_e1000_vtbl;
319+
320+
static void e1000_init(struct e1000 *e, pci_address_t addr) {
321+
e->addr = addr;
322+
e->nif.vtbl = &net_e1000_vtbl;
323+
317324
pci_enable_bus_mastering(e->addr);
318325

319326
for (int i = 0; i < 2; i++) {
@@ -393,11 +400,18 @@ static void e1000_handle_interrupt(interrupt_frame *, void *data) {
393400
e1000_acknowledge_interrupts(e, icr);
394401
}
395402

403+
static void e1000_send_pk(struct net_if *nif, struct pk *pk) {
404+
struct e1000 *e = container_of(struct e1000, nif, nif);
405+
e1000_send(e, pk->data, pk->len);
406+
}
407+
408+
static struct net_if_vtbl net_e1000_vtbl = {
409+
.send = e1000_send_pk,
410+
};
411+
396412
void e1000_test(pci_address_t addr) {
397413
struct e1000 *e = calloc(1, sizeof(struct e1000));
398-
e->addr = addr;
399-
400-
e1000_init(e);
414+
e1000_init(e, addr);
401415
e1000_log_link_status(e);
402416

403417
uint32_t interrupt_state = r32(IMS);

kernel/drv/rtl8139.c

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
#include <ng/debug.h>
44
#include <ng/irq.h>
55
#include <ng/limine.h>
6+
#include <ng/net.h>
67
#include <ng/pci.h>
8+
#include <ng/pk.h>
79
#include <ng/pmm.h>
810
#include <ng/vmm.h>
911
#include <stdio.h>
@@ -18,6 +20,8 @@
1820
#endif
1921

2022
struct rtl8139 {
23+
struct net_if nif;
24+
2125
struct eth_addr mac;
2226

2327
uint16_t io_base;
@@ -76,10 +80,14 @@ static void enable_interrupts(struct rtl8139 *r, int);
7680
static void enable_txrx(struct rtl8139 *r);
7781
static void tx_write(struct rtl8139 *r, uint32_t data, size_t size);
7882
static bool rx_empty(struct rtl8139 *r);
83+
static void rtl8139_send_pk(struct net_if *nif, struct pk *pk);
84+
static struct net_if_vtbl net_rtl8139_vtbl = { .send = rtl8139_send_pk };
7985

8086
void rtl8139_init(struct rtl8139 *r, pci_address_t pci_address) {
8187
verbose_printf("rtl8139: init\n");
8288

89+
r->nif.vtbl = &net_rtl8139_vtbl;
90+
8391
uint32_t bar0 = pci_read32(pci_address, PCI_BAR0);
8492
uint32_t bar1 = pci_read32(pci_address, PCI_BAR1);
8593
if ((bar0 & 1) == 1) {
@@ -192,6 +200,11 @@ void rtl8139_send(struct rtl8139 *r, void *data, size_t size) {
192200
tx_write(r, data_phy, size);
193201
}
194202

203+
static void rtl8139_send_pk(struct net_if *nif, struct pk *pk) {
204+
struct rtl8139 *r = container_of(struct rtl8139, nif, nif);
205+
rtl8139_send(r, pk->data, pk->len);
206+
}
207+
195208
uint16_t *read_packet_header(struct rtl8139 *r) {
196209
return (uint16_t *)(r->rx_buffer + r->rx_index);
197210
}
@@ -219,13 +232,6 @@ ssize_t rtl8139_receive(struct rtl8139 *r, void *data, size_t len) {
219232
return result;
220233
}
221234

222-
void net_debug(int, const void *, size_t);
223-
224-
void print_packet(const void *data, size_t len) {
225-
printf("rtl8139: received packet of length %zu\n", len);
226-
net_debug(0, data, len);
227-
}
228-
229235
void rtl8139_interrupt_handler(interrupt_frame *_, void *rtl) {
230236
struct rtl8139 *r = rtl;
231237

@@ -239,12 +245,11 @@ void rtl8139_interrupt_handler(interrupt_frame *_, void *rtl) {
239245
verbose_printf("rtl8139: rx ok\n");
240246

241247
while (!rx_empty(r)) {
242-
char buffer[2048];
243-
ssize_t len = rtl8139_receive(r, buffer, sizeof(buffer));
244-
#ifdef VERBOSE
245-
if (len > 0)
246-
print_packet(buffer, len);
247-
#endif
248+
struct pk *pk = pk_alloc();
249+
ssize_t len = rtl8139_receive(r, pk->data, sizeof(pk->data));
250+
pk->len = len;
251+
pk->origin_if = &r->nif;
252+
net_ingress(pk);
248253
}
249254

250255
} else if ((int_flag & INTR_RX_ERR) != 0) {
@@ -271,12 +276,5 @@ void rtl_test() {
271276
int irq = pci_read8(pci_address, PCI_INTERRUPT_LINE);
272277

273278
irq_install(irq, rtl8139_interrupt_handler, r);
274-
275-
unsigned char ethernet_frame[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
276-
0x52, 0x54, 0x00, 0x12, 0x34, 0x56, 0x08, 0x06, 0x00, 0x01, 0x08,
277-
0x00, 0x06, 0x04, 0x00, 0x01, 0x52, 0x54, 0x00, 0x12, 0x34, 0x56,
278-
0x0a, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
279-
0x00, 0x02, 0x02 };
280-
rtl8139_send(r, ethernet_frame, sizeof(ethernet_frame));
281279
}
282280
}

kernel/net/arp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <netinet/debug.h>
33
#include <netinet/hdr.h>
44
#include <netinet/in.h>
5+
#include <ng/net.h>
56
#include <ng/pk.h>
67
#include <stdio.h>
78
#include <string.h>
@@ -102,8 +103,10 @@ void arp_ingress(struct pk *pk) {
102103

103104
reply->len = reply->l3_offset + sizeof(struct arp_hdr);
104105

105-
printf("want to send:\n");
106+
printf("sending:\n");
106107
net_debug_pk(reply);
108+
109+
NET_SEND(pk->origin_if, reply);
107110
}
108111

109112
pk_drop(pk);

kernel/net/ip_egress.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
1+
#include <arpa/inet.h>
2+
#include <netinet/hdr.h>
13
#include <ng/net.h>
24
#include <ng/pk.h>
3-
#include <rbtree.h>
45

5-
void ip_egress(struct pk *pk) { }
6+
struct ip_output {
7+
struct net_if *interface;
8+
in_addr_t src_ip;
9+
};
10+
11+
struct ip_output outputs[8];
12+
13+
void ip_egress(struct pk *pk) {
14+
struct ipv4_hdr *ip = (struct ipv4_hdr *)(pk->data + pk->l3_offset);
15+
in_addr_t src_ip = ntohl(ip->src.s_addr);
16+
17+
for (int i = 0; i < 8; i++) {
18+
if (outputs[i].interface == nullptr) {
19+
break;
20+
}
21+
22+
if (outputs[i].src_ip == src_ip) {
23+
struct net_if *net_if = outputs[i].interface;
24+
NET_SEND(net_if, pk);
25+
return;
26+
}
27+
}
28+
}

kernel/net/worker.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <arpa/inet.h>
2+
#include <netinet/hdr.h>
3+
#include <ng/net.h>
4+
#include <ng/pk.h>
5+
6+
struct pk *net_ingress_head = nullptr;
7+
struct pk *net_ingress_tail = nullptr;
8+
9+
void net_worker() {
10+
while (true) { }
11+
}

run.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
stdio: "serial",
99
tee: true,
1010
smp: 2,
11-
network: "e1000",
11+
network: "rtl",
1212
debug_wait: false,
1313
disk_image: "none",
1414
video: false,

0 commit comments

Comments
 (0)