Skip to content

Commit 10ab9ae

Browse files
authored
Merge pull request #3370 from cesanta/l2
Decouple from Ethernet, introduce "l2"
2 parents 756d127 + 66d4069 commit 10ab9ae

File tree

11 files changed

+1715
-771
lines changed

11 files changed

+1715
-771
lines changed

mongoose.c

Lines changed: 760 additions & 343 deletions
Large diffs are not rendered by default.

mongoose.h

Lines changed: 103 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,7 @@ size_t mg_print_ip_port(void (*out)(char, void *), void *arg, va_list *ap);
12421242
size_t mg_print_ip4(void (*out)(char, void *), void *arg, va_list *ap);
12431243
size_t mg_print_ip6(void (*out)(char, void *), void *arg, va_list *ap);
12441244
size_t mg_print_mac(void (*out)(char, void *), void *arg, va_list *ap);
1245+
size_t mg_print_l2addr(void (*out)(char, void *), void *arg, va_list *ap);
12451246

12461247
// Various output functions
12471248
void mg_pfn_iobuf(char ch, void *param); // param: struct mg_iobuf *
@@ -3148,6 +3149,62 @@ bool mg_wifi_ap_stop(void);
31483149

31493150

31503151

3152+
#if MG_ENABLE_TCPIP
3153+
3154+
// no config defaults to 0 => Ethernet
3155+
enum mg_l2type { MG_TCPIP_L2_ETH = 0, MG_TCPIP_L2_PPP }; // MG_TCPIP_L2_PPPoE
3156+
3157+
#if defined(__DCC__)
3158+
#pragma pack(1)
3159+
#else
3160+
#pragma pack(push, 1)
3161+
#endif
3162+
3163+
struct mg_l2addr {
3164+
union {
3165+
uint8_t mac[6];
3166+
} addr;
3167+
};
3168+
3169+
#if defined(__DCC__)
3170+
#pragma pack(0)
3171+
#else
3172+
#pragma pack(pop)
3173+
#endif
3174+
3175+
#if 0
3176+
TODO(): ?
3177+
struct eth_opts {
3178+
bool enable_crc32_check; // Do a CRC check on RX frames and strip it
3179+
bool enable_mac_check; // Do a MAC check on RX frames
3180+
};
3181+
struct mg_l2opts {
3182+
union {
3183+
struct eth_opts eth;
3184+
};
3185+
};
3186+
#endif
3187+
3188+
enum mg_l2proto {
3189+
MG_TCPIP_L2PROTO_IPV4 = 0,
3190+
MG_TCPIP_L2PROTO_IPV6,
3191+
MG_TCPIP_L2PROTO_ARP,
3192+
MG_TCPIP_L2PROTO_PPPoE_DISC,
3193+
MG_TCPIP_L2PROTO_PPPoE_SESS
3194+
};
3195+
enum mg_l2addrtype {
3196+
MG_TCPIP_L2ADDR_BCAST,
3197+
MG_TCPIP_L2ADDR_MCAST,
3198+
MG_TCPIP_L2ADDR_MCAST6
3199+
};
3200+
3201+
#endif
3202+
3203+
3204+
3205+
3206+
3207+
31513208

31523209

31533210
#if MG_ENABLE_TCPIP
@@ -3165,29 +3222,32 @@ typedef void (*mg_tcpip_event_handler_t)(struct mg_tcpip_if *ifp, int ev,
31653222
void *ev_data);
31663223

31673224
enum {
3168-
MG_TCPIP_EV_ST_CHG, // state change uint8_t * (&ifp->state)
3169-
MG_TCPIP_EV_DHCP_DNS, // DHCP DNS assignment uint32_t *ipaddr
3170-
MG_TCPIP_EV_DHCP_SNTP, // DHCP SNTP assignment uint32_t *ipaddr
3171-
MG_TCPIP_EV_ARP, // Got ARP packet struct mg_str *
3172-
MG_TCPIP_EV_TIMER_1S, // 1 second timer NULL
3173-
MG_TCPIP_EV_WIFI_SCAN_RESULT, // Wi-Fi scan results struct mg_wifi_scan_bss_data *
3174-
MG_TCPIP_EV_WIFI_SCAN_END, // Wi-Fi scan has finished NULL
3175-
MG_TCPIP_EV_WIFI_CONNECT_ERR, // Wi-Fi connect has failed driver and chip specific
3176-
MG_TCPIP_EV_DRIVER, // Driver event driver specific
3177-
MG_TCPIP_EV_ST6_CHG, // state6 change uint8_t * (&ifp->state6)
3178-
MG_TCPIP_EV_USER // Starting ID for user events
3225+
MG_TCPIP_EV_ST_CHG, // state change uint8_t * (&ifp->state)
3226+
MG_TCPIP_EV_DHCP_DNS, // DHCP DNS assignment uint32_t *ipaddr
3227+
MG_TCPIP_EV_DHCP_SNTP, // DHCP SNTP assignment uint32_t *ipaddr
3228+
MG_TCPIP_EV_ARP, // Got ARP packet struct mg_str *
3229+
MG_TCPIP_EV_TIMER_1S, // 1 second timer NULL
3230+
MG_TCPIP_EV_WIFI_SCAN_RESULT, // Wi-Fi scan results struct
3231+
// mg_wifi_scan_bss_data *
3232+
MG_TCPIP_EV_WIFI_SCAN_END, // Wi-Fi scan has finished NULL
3233+
MG_TCPIP_EV_WIFI_CONNECT_ERR, // Wi-Fi connect has failed driver and
3234+
// chip specific
3235+
MG_TCPIP_EV_DRIVER, // Driver event driver specific
3236+
MG_TCPIP_EV_ST6_CHG, // state6 change uint8_t *
3237+
// (&ifp->state6)
3238+
MG_TCPIP_EV_USER // Starting ID for user events
31793239
};
31803240

31813241
// Network interface
31823242
struct mg_tcpip_if {
3183-
uint8_t mac[6]; // MAC address. Must be set to a valid MAC
3184-
uint32_t ip, mask, gw; // IP address, mask, default gateway
3185-
struct mg_str tx; // Output (TX) buffer
3186-
bool enable_dhcp_client; // Enable DCHP client
3187-
bool enable_dhcp_server; // Enable DCHP server
3188-
bool enable_get_gateway; // DCHP server sets client as gateway
3189-
bool enable_req_dns; // DCHP client requests DNS server
3190-
bool enable_req_sntp; // DCHP client requests SNTP server
3243+
uint8_t mac[sizeof(struct mg_l2addr)]; // hw address. Set to a valid addr
3244+
uint32_t ip, mask, gw; // IP address, mask, default gateway
3245+
struct mg_str tx; // Output (TX) buffer
3246+
bool enable_dhcp_client; // Enable DCHP client
3247+
bool enable_dhcp_server; // Enable DCHP server
3248+
bool enable_get_gateway; // DCHP server sets client as gateway
3249+
bool enable_req_dns; // DCHP client requests DNS server
3250+
bool enable_req_sntp; // DCHP client requests SNTP server
31913251
bool enable_crc32_check; // Do a CRC check on RX frames and strip it
31923252
bool enable_mac_check; // Do a MAC check on RX frames
31933253
bool update_mac_hash_table; // Signal drivers to update MAC controller
@@ -3198,21 +3258,22 @@ struct mg_tcpip_if {
31983258
struct mg_mgr *mgr; // Mongoose event manager
31993259
struct mg_queue recv_queue; // Receive queue
32003260
char dhcp_name[MG_TCPIP_DHCPNAME_SIZE]; // Name for DHCP, "mip" if unset
3201-
uint16_t mtu; // Interface MTU
3202-
#define MG_TCPIP_MTU_DEFAULT 1500
3261+
uint16_t mtu; // Interface link payload
3262+
uint16_t framesize; // Interface frame max length
32033263
#if MG_ENABLE_IPV6
3204-
uint64_t ip6ll[2], ip6[2]; // IPv6 link-local and global addresses
3205-
uint8_t prefix[8]; // IPv6 global address prefix
3206-
uint8_t prefix_len; // Prefix length
3207-
uint64_t gw6[2]; // Default gateway
3208-
bool enable_slaac; // Enable IPv6 address autoconfiguration
3209-
bool enable_dhcp6_client; // Enable DCHPv6 client
3264+
uint64_t ip6ll[2], ip6[2]; // IPv6 link-local and global addresses,
3265+
uint8_t prefix[8]; // prefix,
3266+
uint8_t prefix_len; // prefix length,
3267+
uint64_t gw6[2]; // default gateway.
3268+
bool enable_slaac; // Enable IPv6 address autoconfiguration
3269+
bool enable_dhcp6_client; // Enable DCHPv6 client TODO()
32103270
#endif
32113271

32123272
// Internal state, user can use it but should not change it
3213-
uint8_t gwmac[6]; // Router's MAC
3214-
char *dns4_url; // DNS server URL
3215-
uint64_t now; // Current time
3273+
uint8_t gwmac[sizeof(struct mg_l2addr)]; // Router's hw address
3274+
enum mg_l2type l2type; // Ethernet, PPP, etc.
3275+
char *dns4_url; // DNS server URL
3276+
uint64_t now; // Current time
32163277
uint64_t timer_1000ms; // 1000 ms timer: for DHCP and link state
32173278
uint64_t lease_expire; // Lease expiration time, in ms
32183279
uint16_t eport; // Next ephemeral port
@@ -3228,11 +3289,12 @@ struct mg_tcpip_if {
32283289
#define MG_TCPIP_STATE_READY 4 // Interface has fully come up, ready to work
32293290
bool gw_ready; // We've got a hw address for the router
32303291
#if MG_ENABLE_IPV6
3231-
uint8_t gw6mac[6]; // IPv6 Router's MAC
3232-
uint8_t state6; // Current IPv6 state
3233-
bool gw6_ready; // We've got a hw address for the IPv6 router
3292+
uint8_t gw6mac[sizeof(struct mg_l2addr)]; // IPV6 Router's hw address
3293+
uint8_t state6; // Current IPv6 state
3294+
bool gw6_ready; // We've got a hw address for the IPv6 router
32343295
#endif
32353296
};
3297+
32363298
void mg_tcpip_init(struct mg_mgr *, struct mg_tcpip_if *);
32373299
void mg_tcpip_free(struct mg_tcpip_if *);
32383300
void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
@@ -3264,39 +3326,38 @@ struct mg_tcpip_spi {
32643326
uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
32653327
};
32663328

3267-
32683329
// Alignment and memory section requirements
32693330
#ifndef MG_8BYTE_ALIGNED
32703331
#if defined(__GNUC__)
32713332
#define MG_8BYTE_ALIGNED __attribute__((aligned((8U))))
32723333
#else
32733334
#define MG_8BYTE_ALIGNED
3274-
#endif // compiler
3275-
#endif // 8BYTE_ALIGNED
3335+
#endif // compiler
3336+
#endif // 8BYTE_ALIGNED
32763337

32773338
#ifndef MG_16BYTE_ALIGNED
32783339
#if defined(__GNUC__)
32793340
#define MG_16BYTE_ALIGNED __attribute__((aligned((16U))))
32803341
#else
32813342
#define MG_16BYTE_ALIGNED
3282-
#endif // compiler
3283-
#endif // 16BYTE_ALIGNED
3343+
#endif // compiler
3344+
#endif // 16BYTE_ALIGNED
32843345

32853346
#ifndef MG_32BYTE_ALIGNED
32863347
#if defined(__GNUC__)
32873348
#define MG_32BYTE_ALIGNED __attribute__((aligned((32U))))
32883349
#else
32893350
#define MG_32BYTE_ALIGNED
3290-
#endif // compiler
3291-
#endif // 32BYTE_ALIGNED
3351+
#endif // compiler
3352+
#endif // 32BYTE_ALIGNED
32923353

32933354
#ifndef MG_64BYTE_ALIGNED
32943355
#if defined(__GNUC__)
32953356
#define MG_64BYTE_ALIGNED __attribute__((aligned((64U))))
32963357
#else
32973358
#define MG_64BYTE_ALIGNED
3298-
#endif // compiler
3299-
#endif // 64BYTE_ALIGNED
3359+
#endif // compiler
3360+
#endif // 64BYTE_ALIGNED
33003361

33013362
#ifndef MG_ETH_RAM
33023363
#define MG_ETH_RAM

src/l2.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#include "l2.h"
2+
#include "net.h"
3+
#include "net_builtin.h"
4+
5+
#if MG_ENABLE_TCPIP
6+
7+
// L2 API
8+
void mg_l2_init(enum mg_l2type type, uint8_t *addr, uint16_t *mtu,
9+
uint16_t *framesize);
10+
uint8_t *mg_l2_header(enum mg_l2type type, enum mg_l2proto proto, uint8_t *src,
11+
uint8_t *dst, uint8_t *frame);
12+
size_t mg_l2_footer(enum mg_l2type type, size_t len, uint8_t *frame);
13+
bool mg_l2_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
14+
struct mg_str *pay, struct mg_str *raw);
15+
// TODO(): ? bool mg_l2_rx(enum mg_l2type type, struct mg_l2opts *opts, uint8_t
16+
// *addr, enum mg_l2proto *proto, struct mg_str *pay, struct mg_str *raw);
17+
uint8_t *mg_l2_getaddr(enum mg_l2type type, uint8_t *frame);
18+
uint8_t *mg_l2_mapip(enum mg_l2type type, enum mg_l2addrtype addrtype,
19+
struct mg_addr *ip);
20+
bool mg_l2_genip6(enum mg_l2type type, uint64_t *ip6, uint8_t prefix_len,
21+
uint8_t *addr);
22+
bool mg_l2_ip6get(enum mg_l2type type, uint8_t *addr, uint8_t *opts,
23+
uint8_t len);
24+
uint8_t mg_l2_ip6put(enum mg_l2type type, uint8_t *addr, uint8_t *opts);
25+
26+
// clang-format off
27+
extern void mg_l2_eth_init(struct mg_l2addr *, uint16_t *, uint16_t *);
28+
extern uint8_t *mg_l2_eth_header(enum mg_l2proto, struct mg_l2addr *, struct mg_l2addr *, uint8_t *);
29+
extern size_t mg_l2_eth_footer(size_t, uint8_t *);
30+
extern bool mg_l2_eth_rx(struct mg_tcpip_if *, enum mg_l2proto *, struct mg_str *, struct mg_str *);
31+
extern struct mg_l2addr *mg_l2_eth_getaddr(uint8_t *);
32+
extern struct mg_l2addr *mg_l2_eth_mapip(enum mg_l2addrtype, struct mg_addr *);
33+
extern bool mg_l2_eth_genip6(uint64_t *, uint8_t, struct mg_l2addr *);
34+
extern bool mg_l2_eth_ip6get(struct mg_l2addr *, uint8_t *, uint8_t);
35+
extern uint8_t mg_l2_eth_ip6put(struct mg_l2addr *, uint8_t *);
36+
37+
extern void mg_l2_ppp_init(struct mg_l2addr *, uint16_t *, uint16_t *);
38+
extern uint8_t *mg_l2_ppp_header(enum mg_l2proto, struct mg_l2addr *, struct mg_l2addr *, uint8_t *);
39+
extern size_t mg_l2_ppp_footer(size_t, uint8_t *);
40+
extern bool mg_l2_ppp_rx(struct mg_tcpip_if *, enum mg_l2proto *, struct mg_str *, struct mg_str *);
41+
extern struct mg_l2addr *mg_l2_ppp_getaddr(uint8_t *);
42+
extern struct mg_l2addr *mg_l2_ppp_mapip(enum mg_l2addrtype, struct mg_addr *);
43+
#if MG_ENABLE_IPV6
44+
extern bool mg_l2_ppp_genip6(uint64_t *, uint8_t, struct mg_l2addr *);
45+
extern bool mg_l2_ppp_ip6get(struct mg_l2addr *, uint8_t *, uint8_t);
46+
extern uint8_t mg_l2_ppp_ip6put(struct mg_l2addr *, uint8_t *);
47+
#endif
48+
49+
typedef void (*l2_init_fn)(struct mg_l2addr *, uint16_t *, uint16_t *);
50+
typedef uint8_t *((*l2_header_fn)(enum mg_l2proto, struct mg_l2addr *, struct mg_l2addr *, uint8_t *));
51+
typedef size_t (*l2_footer_fn)(size_t, uint8_t *);
52+
typedef bool (*l2_rx_fn)(struct mg_tcpip_if *, enum mg_l2proto *, struct mg_str *, struct mg_str *);
53+
typedef struct mg_l2addr (*(*l2_getaddr_fn)(uint8_t *));
54+
typedef struct mg_l2addr (*(*l2_mapip_fn)(enum mg_l2addrtype, struct mg_addr *));
55+
#if MG_ENABLE_IPV6
56+
typedef bool (*l2_genip6_fn)(uint64_t *, uint8_t, struct mg_l2addr *);
57+
typedef bool (*l2_ip6get_fn)(struct mg_l2addr *, uint8_t *, uint8_t);
58+
typedef uint8_t (*l2_ip6put_fn)(struct mg_l2addr *, uint8_t *);
59+
#endif
60+
// clang-format on
61+
62+
static const l2_init_fn l2_init[] = {mg_l2_eth_init, mg_l2_ppp_init};
63+
static const l2_header_fn l2_header[] = {mg_l2_eth_header, mg_l2_ppp_header};
64+
static const l2_footer_fn l2_footer[] = {mg_l2_eth_footer, mg_l2_ppp_footer};
65+
static const l2_rx_fn l2_rx[] = {mg_l2_eth_rx, mg_l2_ppp_rx};
66+
static const l2_getaddr_fn l2_getaddr[] = {mg_l2_eth_getaddr,
67+
mg_l2_ppp_getaddr};
68+
static const l2_mapip_fn l2_mapip[] = {mg_l2_eth_mapip, mg_l2_ppp_mapip};
69+
#if MG_ENABLE_IPV6
70+
static const l2_genip6_fn l2_genip6[] = {mg_l2_eth_genip6, mg_l2_ppp_genip6};
71+
static const l2_ip6get_fn l2_ip6get[] = {mg_l2_eth_ip6get, mg_l2_ppp_ip6get};
72+
static const l2_ip6put_fn l2_ip6put[] = {mg_l2_eth_ip6put, mg_l2_ppp_ip6put};
73+
#endif
74+
75+
void mg_l2_init(enum mg_l2type type, uint8_t *addr, uint16_t *mtu,
76+
uint16_t *framesize) {
77+
l2_init[type]((struct mg_l2addr *) addr, mtu, framesize);
78+
}
79+
80+
uint8_t *mg_l2_header(enum mg_l2type type, enum mg_l2proto proto, uint8_t *src,
81+
uint8_t *dst, uint8_t *frame) {
82+
return l2_header[type](proto, (struct mg_l2addr *) src,
83+
(struct mg_l2addr *) dst, frame);
84+
}
85+
86+
size_t mg_l2_footer(enum mg_l2type type, size_t len, uint8_t *frame) {
87+
return l2_footer[type](len, frame);
88+
}
89+
90+
bool mg_l2_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
91+
struct mg_str *pay, struct mg_str *raw) {
92+
return l2_rx[ifp->l2type](ifp, proto, pay, raw);
93+
}
94+
95+
uint8_t *mg_l2_getaddr(enum mg_l2type type, uint8_t *frame) {
96+
return (uint8_t *) l2_getaddr[type](frame);
97+
}
98+
99+
struct mg_l2addr s_mapip;
100+
101+
uint8_t *mg_l2_mapip(enum mg_l2type type, enum mg_l2addrtype addrtype,
102+
struct mg_addr *ip) {
103+
return (uint8_t *) l2_mapip[type](addrtype, ip);
104+
}
105+
106+
#if MG_ENABLE_IPV6
107+
bool mg_l2_genip6(enum mg_l2type type, uint64_t *ip6, uint8_t prefix_len,
108+
uint8_t *addr) {
109+
return l2_genip6[type](ip6, prefix_len, (struct mg_l2addr *) addr);
110+
}
111+
112+
bool mg_l2_ip6get(enum mg_l2type type, uint8_t *addr, uint8_t *opts,
113+
uint8_t len) {
114+
return l2_ip6get[type]((struct mg_l2addr *) addr, opts, len);
115+
}
116+
uint8_t mg_l2_ip6put(enum mg_l2type type, uint8_t *addr, uint8_t *opts) {
117+
return l2_ip6put[type]((struct mg_l2addr *) addr, opts);
118+
}
119+
#endif
120+
121+
#endif

src/l2.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#pragma once
2+
3+
#include "arch.h"
4+
#include "config.h"
5+
6+
#if MG_ENABLE_TCPIP
7+
8+
// no config defaults to 0 => Ethernet
9+
enum mg_l2type { MG_TCPIP_L2_ETH = 0, MG_TCPIP_L2_PPP }; // MG_TCPIP_L2_PPPoE
10+
11+
#if defined(__DCC__)
12+
#pragma pack(1)
13+
#else
14+
#pragma pack(push, 1)
15+
#endif
16+
17+
struct mg_l2addr {
18+
union {
19+
uint8_t mac[6];
20+
} addr;
21+
};
22+
23+
#if defined(__DCC__)
24+
#pragma pack(0)
25+
#else
26+
#pragma pack(pop)
27+
#endif
28+
29+
#if 0
30+
TODO(): ?
31+
struct eth_opts {
32+
bool enable_crc32_check; // Do a CRC check on RX frames and strip it
33+
bool enable_mac_check; // Do a MAC check on RX frames
34+
};
35+
struct mg_l2opts {
36+
union {
37+
struct eth_opts eth;
38+
};
39+
};
40+
#endif
41+
42+
enum mg_l2proto {
43+
MG_TCPIP_L2PROTO_IPV4 = 0,
44+
MG_TCPIP_L2PROTO_IPV6,
45+
MG_TCPIP_L2PROTO_ARP,
46+
MG_TCPIP_L2PROTO_PPPoE_DISC,
47+
MG_TCPIP_L2PROTO_PPPoE_SESS
48+
};
49+
enum mg_l2addrtype {
50+
MG_TCPIP_L2ADDR_BCAST,
51+
MG_TCPIP_L2ADDR_MCAST,
52+
MG_TCPIP_L2ADDR_MCAST6
53+
};
54+
55+
#endif

0 commit comments

Comments
 (0)