Skip to content

Commit 615349f

Browse files
authored
Merge pull request #41 from rtbrick/dev
Dev
2 parents 800f6eb + 6cda009 commit 615349f

15 files changed

Lines changed: 226 additions & 17 deletions

docs/config.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ Attribute | Description | Default
171171
`address-ipv6` | Local network interface IPv6 address (implicitly /64) | -
172172
`gateway-ipv6` | Gateway network interface IPv6 address (implicitly /64)
173173
`vlan` | Network interface VLAN | 0 (untagged)
174+
`gateway-mac`| Optional set gateway MAC address manually
174175

175176
### Access Interfaces
176177

@@ -181,6 +182,7 @@ Attribute | Description | Default
181182
`interface` | Access interface name (e.g. eth0, ...)
182183
`type` | Switch the access type between `pppoe` (PPP over Ethernet) and `ipoe` (IP over Ethernet) | pppoe
183184
`vlan-mode` | Set VLAN mode `1:1` or `N:1` | 1:1
185+
`qinq` | Set outer VLAN ethertype to QinQ (0x88a8) | false
184186
`outer-vlan-min` | Outer VLAN minimum value | 0 (untagged)
185187
`outer-vlan-max` | Outer VLAN maximum value | 0 (untagged)
186188
`outer-vlan` |Set outer-vlan-min/max equally
@@ -447,6 +449,8 @@ Attribute | Description | Default
447449
`keepalive-interval` | LCP echo request interval in seconds (0 means disabled) | 30
448450
`keepalive-retry` | PPP LCP echo request max retry | 3
449451
`start-delay` | PPP LCP initial request delay in milliseconds | 0
452+
`ignore-vendor-specific` | Ignore LCP vendor specific requests | false
453+
`connection-status-message` | Accept LCP connection status messages | false
450454

451455
### PPP IPCP
452456

@@ -608,7 +612,7 @@ Attribute | Description | Default
608612
`direction` | Mandatory stream direction (`upstream`, `downstream` or `both`) | `both`
609613
`priority` | IPv4 TOS / IPv6 TC | 0
610614
`vlan-priority` | VLAN priority | 0
611-
`length` | Layer 3 (IP + payload) traffic length (76 - 1500) | 128
615+
`length` | Layer 3 (IP + payload) traffic length (76 - 9000) | 128
612616
`pps` | Stream traffic rate in packets per second | 1
613617
`bps` | Stream traffic rate in bits per second (layer 3) |
614618
`network-ipv4-address` | Overwrite network interface IPv4 address |

docs/ipoe.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ The most common case for IPoE is using DHCPv4/v6 as shown below.
5858
}
5959
```
6060

61+
## IPoE Session Information
62+
6163
The control socket command `session-info session-id <id>` provides
62-
detailed information for IPOE sessions.
64+
detailed information for IPoE sessions.
6365

6466
`$ sudo bngblaster-cli run.sock session-info session-id 1 | jq .`
6567
```json

docs/pppoe.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,24 @@ detailed explained in the configuration section.
9696
}
9797
```
9898

99+
## LCP Vendor Extension
100+
101+
This chapter refers to RFC 2153 PPP vendor extensions.
102+
103+
Per default all LCP vendor specific requests will be rejected sending a
104+
LCP code reject message. With `ppp->lcp->ignore-vendor-specific` enabled,
105+
those messages will be ignored as required to emulate different CPE
106+
behaviors.
107+
108+
The option `ppp->lcp->connection-status-message` allows to accept LCP vendor requests
109+
with any OUI if kind is set to `1` by responding with vendor request of
110+
kind `2`. The OUI from request is copied to response in this case.
111+
The value from request is stored in the session as `connection-status-message`.
112+
113+
## PPPoE Session Information
114+
99115
The control socket command `session-info session-id <id>` provides
100-
detailed information for IPOE sessions.
116+
detailed information for PPPoE sessions.
101117

102118
`$ sudo bngblaster-cli run.sock session-info session-id 1 | jq .`
103119
```json

src/bbl.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,8 @@ main (int argc, char *argv[])
715715
exit(1);
716716
}
717717
ctx->op.network_if->access = false;
718+
/* Copy gateway MAC from config (default 00:00:00:00:00:00) */
719+
memcpy(ctx->op.network_if->gateway_mac, ctx->config.gateway_mac, ETH_ADDR_LEN);
718720
if(ctx->config.network_ip && ctx->config.network_gateway) {
719721
if(ctx->config.network_ip && ctx->config.network_gateway) {
720722
ctx->op.network_if->ip = ctx->config.network_ip;

src/bbl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ typedef struct bbl_access_config_
364364
uint16_t access_inner_vlan_max;
365365
uint16_t access_third_vlan;
366366

367+
bool qinq; /* use ethertype 0x8818 */
368+
367369
/* Static */
368370
uint32_t static_ip;
369371
uint32_t static_ip_iter;
@@ -568,6 +570,8 @@ typedef struct bbl_ctx_
568570
char network_if[IFNAMSIZ];
569571
uint32_t network_ip;
570572
uint32_t network_gateway;
573+
uint8_t gateway_mac[ETH_ADDR_LEN];
574+
571575
ipv6_prefix network_ip6;
572576
ipv6_prefix network_gateway6;
573577
uint16_t network_vlan;
@@ -626,6 +630,8 @@ typedef struct bbl_ctx_
626630
uint16_t lcp_keepalive_interval;
627631
uint16_t lcp_keepalive_retry;
628632
uint16_t lcp_start_delay;
633+
bool lcp_vendor_ignore;
634+
bool lcp_connection_status_message;
629635

630636
/* Authentication */
631637
uint16_t authentication_timeout;
@@ -881,6 +887,9 @@ typedef struct bbl_session_
881887
uint16_t auth_protocol; /* PAP or CHAP */
882888
uint8_t auth_retries;
883889

890+
char *reply_message;
891+
char *connections_status_message;
892+
884893
/* IPCP */
885894
ppp_state_t ipcp_state;
886895
uint8_t ipcp_response_code;

src/bbl_config.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ json_parse_access_interface (bbl_ctx_s *ctx, json_t *access_interface, bbl_acces
277277
return false;
278278
}
279279

280+
value = json_object_get(access_interface, "qinq");
281+
if (json_is_boolean(value)) {
282+
access_config->qinq = json_boolean_value(value);
283+
}
280284
value = json_object_get(access_interface, "outer-vlan");
281285
if (json_is_number(value)) {
282286
access_config->access_outer_vlan_min = json_number_value(value);
@@ -584,7 +588,7 @@ json_parse_stream (bbl_ctx_s *ctx, json_t *stream, bbl_stream_config *stream_con
584588
value = json_object_get(stream, "length");
585589
if (value) {
586590
stream_config->length = json_number_value(value);
587-
if(stream_config->length < 76 || stream_config->length > 1500) {
591+
if(stream_config->length < 76 || stream_config->length > 9000) {
588592
fprintf(stderr, "JSON config error: Invalid value for stream->length\n");
589593
return false;
590594
}
@@ -868,6 +872,14 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) {
868872
return false;
869873
}
870874
}
875+
value = json_object_get(sub, "ignore-vendor-specific");
876+
if (json_is_boolean(value)) {
877+
ctx->config.lcp_vendor_ignore = json_boolean_value(value);
878+
}
879+
value = json_object_get(sub, "connection-status-message");
880+
if (json_is_boolean(value)) {
881+
ctx->config.lcp_connection_status_message = json_boolean_value(value);
882+
}
871883
}
872884
sub = json_object_get(section, "ipcp");
873885
if (json_is_object(sub)) {
@@ -1175,6 +1187,19 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) {
11751187
}
11761188
ctx->config.network_gateway6.len = 64;
11771189
}
1190+
if (json_unpack(sub, "{s:s}", "gateway-mac", &s) == 0) {
1191+
if (sscanf(s, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
1192+
&ctx->config.gateway_mac[0],
1193+
&ctx->config.gateway_mac[1],
1194+
&ctx->config.gateway_mac[2],
1195+
&ctx->config.gateway_mac[3],
1196+
&ctx->config.gateway_mac[4],
1197+
&ctx->config.gateway_mac[5]) < 6)
1198+
{
1199+
fprintf(stderr, "JSON config error: Invalid value for network->gateway-mac\n");
1200+
return false;
1201+
}
1202+
}
11781203
value = json_object_get(sub, "vlan");
11791204
if (json_is_number(value)) {
11801205
ctx->config.network_vlan = json_number_value(value);

src/bbl_ctrl.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ bbl_ctrl_session_info(int fd, bbl_ctx_s *ctx, uint32_t session_id, json_t* argum
504504
}
505505

506506
if(session->access_type == ACCESS_TYPE_PPPOE) {
507-
root = json_pack("{ss si s{ss si ss ss si si ss ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* si si si so*}}",
507+
root = json_pack("{ss si s{ss si ss ss si si ss ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* si si si so*}}",
508508
"status", "ok",
509509
"code", 200,
510510
"session-info",
@@ -518,6 +518,8 @@ bbl_ctrl_session_info(int fd, bbl_ctx_s *ctx, uint32_t session_id, json_t* argum
518518
"username", session->username,
519519
"agent-circuit-id", session->agent_circuit_id,
520520
"agent-remote-id", session->agent_remote_id,
521+
"reply-message", session->reply_message,
522+
"connection-status-message", session->connections_status_message,
521523
"lcp-state", ppp_state_string(session->lcp_state),
522524
"ipcp-state", ppp_state_string(session->ipcp_state),
523525
"ip6cp-state", ppp_state_string(session->ip6cp_state),

src/bbl_interactive.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
typedef enum {
2121
UI_VIEW_DEFAULT = 0,
2222
UI_VIEW_ACCESS_IF_STATS,
23-
UI_VIEW_STREAMS,
23+
UI_VIEW_SESSION,
2424
UI_VIEW_MAX,
2525
} __attribute__ ((__packed__)) bbl_ui_view;
2626

@@ -49,7 +49,7 @@ bbl_init_stats_win()
4949
wclear(stats_win);
5050
wattron(stats_win, COLOR_PAIR(COLOR_GREEN));
5151
wprintw(stats_win, "F1: Select View F7/F8: Start/Stop Traffic F9: Terminate Sessions\n");
52-
if(g_view_selected == UI_VIEW_STREAMS) {
52+
if(g_view_selected == UI_VIEW_SESSION) {
5353
wprintw(stats_win, "Left/Right: Select Session\n");
5454
} else {
5555
wprintw(stats_win, "Left/Right: Select Interface\n");
@@ -93,7 +93,7 @@ bbl_read_key_job (timer_s *timer)
9393
bbl_init_stats_win();
9494
break;
9595
case KEY_LEFT:
96-
if(g_view_selected == UI_VIEW_STREAMS) {
96+
if(g_view_selected == UI_VIEW_SESSION) {
9797
if(g_session_selected > 1) {
9898
g_session_selected--;
9999
} else {
@@ -108,7 +108,7 @@ bbl_read_key_job (timer_s *timer)
108108
bbl_init_stats_win();
109109
break;
110110
case KEY_RIGHT:
111-
if(g_view_selected == UI_VIEW_STREAMS) {
111+
if(g_view_selected == UI_VIEW_SESSION) {
112112
g_session_selected++;
113113
if(g_session_selected > ctx->sessions) {
114114
g_session_selected = 1;
@@ -407,8 +407,8 @@ bbl_stats_job (timer_s *timer)
407407
wprintw(stats_win, "\nAccess Interface Protocol Stats");
408408
}
409409

410-
} else if(g_view_selected == UI_VIEW_STREAMS) {
411-
wprintw(stats_win, "\nSession Stream Stats ( Session-Id: ", g_session_selected);
410+
} else if(g_view_selected == UI_VIEW_SESSION) {
411+
wprintw(stats_win, "\nSession and Streams ( Session-Id: ", g_session_selected);
412412
wattron(stats_win, COLOR_PAIR(COLOR_GREEN));
413413
wprintw(stats_win, "%u", g_session_selected);
414414
wattroff(stats_win, COLOR_PAIR(COLOR_GREEN));
@@ -425,6 +425,15 @@ bbl_stats_job (timer_s *timer)
425425
if(session->agent_remote_id) {
426426
wprintw(stats_win, " ACI: %s \n", session->agent_circuit_id);
427427
}
428+
if(session->connections_status_message || session->reply_message) {
429+
wprintw(stats_win, "\n");
430+
if(session->reply_message) {
431+
wprintw(stats_win, " Reply-Message: %s \n", session->reply_message);
432+
}
433+
if(session->connections_status_message) {
434+
wprintw(stats_win, " Connection-Status-Message: %s \n", session->connections_status_message);
435+
}
436+
}
428437
wprintw(stats_win, "\n Access Client Interface\n");
429438
wprintw(stats_win, " Tx Packets %10lu | %7lu PPS | %10lu Kbps\n",
430439
session->stats.packets_tx, session->stats.rate_packets_tx.avg,

src/bbl_protocols.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1816,7 +1816,11 @@ encode_ethernet(uint8_t *buf, uint16_t *len,
18161816

18171817
/* Add VLAN header */
18181818
if(eth->vlan_outer) {
1819-
*(uint16_t*)buf = htobe16(ETH_TYPE_VLAN);
1819+
if(eth->qinq) {
1820+
*(uint16_t*)buf = htobe16(ETH_TYPE_QINQ);
1821+
} else {
1822+
*(uint16_t*)buf = htobe16(ETH_TYPE_VLAN);
1823+
}
18201824
BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t));
18211825
eth->vlan_outer |= eth->vlan_outer_priority << 13;
18221826
*(uint16_t*)buf = htobe16(eth->vlan_outer);
@@ -2960,6 +2964,9 @@ decode_ppp_lcp(uint8_t *buf, uint16_t len,
29602964
lcp = (bbl_lcp_t*)sp; BUMP_BUFFER(sp, sp_len, sizeof(bbl_lcp_t));
29612965
memset(lcp, 0x0, sizeof(bbl_lcp_t));
29622966

2967+
lcp->start = buf;
2968+
lcp->len = len;
2969+
29632970
lcp->code = *buf;
29642971
BUMP_BUFFER(buf, len, sizeof(uint8_t));
29652972
lcp->identifier = *buf;
@@ -2986,6 +2993,20 @@ decode_ppp_lcp(uint8_t *buf, uint16_t len,
29862993
lcp->options_len = lcp_len;
29872994

29882995
switch(lcp->code) {
2996+
case PPP_CODE_VENDOR_SPECIFIC:
2997+
/* RFC 2153 */
2998+
if(lcp_len < 8) {
2999+
return DECODE_ERROR;
3000+
}
3001+
lcp->magic = *(uint32_t*)buf;
3002+
BUMP_BUFFER(buf, lcp_len, sizeof(uint32_t));
3003+
memcpy(lcp->vendor_oui, buf, OUI_LEN);
3004+
BUMP_BUFFER(buf, lcp_len, OUI_LEN);
3005+
lcp->vendor_kind = *buf;
3006+
BUMP_BUFFER(buf, lcp_len, sizeof(uint8_t));
3007+
lcp->vendor_value = buf;
3008+
lcp->vendor_value_len = lcp_len;
3009+
break;
29893010
case PPP_CODE_ECHO_REQUEST:
29903011
case PPP_CODE_ECHO_REPLY:
29913012
if(lcp_len>=4) {

src/bbl_protocols.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
#define ETH_VLAN_ID_MAX 4095
4949
#define ETH_VLAN_PBIT_MAX 7
5050

51+
#define OUI_LEN 3
52+
5153
#define IPV4_RF 0x8000 /* reserved fragment flag */
5254
#define IPV4_DF 0x4000 /* dont fragment flag */
5355
#define IPV4_MF 0x2000 /* more fragments flag */
@@ -83,6 +85,7 @@
8385
#define ICMP_TYPE_ECHO_REPLY 0x00
8486
#define ICMP_TYPE_ECHO_REQUEST 0x08
8587

88+
#define PPP_CODE_VENDOR_SPECIFIC 0
8689
#define PPP_CODE_CONF_REQUEST 1
8790
#define PPP_CODE_CONF_ACK 2
8891
#define PPP_CODE_CONF_NAK 3
@@ -471,6 +474,7 @@ typedef struct access_line_ {
471474
typedef struct bbl_ethernet_header_ {
472475
uint8_t *dst; // destination MAC address
473476
uint8_t *src; // source MAC address
477+
bool qinq; // ethertype 0x88a8
474478
uint16_t vlan_outer; // outer VLAN identifier
475479
uint16_t vlan_inner; // inner VLAN identifier
476480
uint16_t vlan_three; // third VLAN
@@ -532,6 +536,12 @@ typedef struct bbl_lcp_ {
532536
uint16_t mru;
533537
uint16_t auth;
534538
uint32_t magic;
539+
uint8_t vendor_oui[OUI_LEN];
540+
uint8_t vendor_kind;
541+
uint8_t *vendor_value;
542+
uint16_t vendor_value_len;
543+
uint8_t *start;
544+
uint16_t len;
535545
} bbl_lcp_t;
536546

537547
/*

0 commit comments

Comments
 (0)