From 8ceb45a07f4e22df56629bc4e9108d7f25f8fba2 Mon Sep 17 00:00:00 2001 From: Christian Giese Date: Thu, 17 Jun 2021 14:19:50 +0200 Subject: [PATCH] Add Access-Line Profiles Add new access-line-profiles and support for all those atributes in the PPPoE BBF vendor specific tag. --- docs/config.md | 118 ++++++++++++++++-- src/bbl.h | 51 ++++++++ src/bbl_config.c | 164 ++++++++++++++++++++++++- src/bbl_protocols.c | 291 +++++++++++++++++++++++++++++++++++++++++++- src/bbl_protocols.h | 5 +- src/bbl_session.c | 14 ++- src/bbl_tx.c | 2 + 7 files changed, 621 insertions(+), 24 deletions(-) diff --git a/docs/config.md b/docs/config.md index 0f4830e4..226cb2f1 100644 --- a/docs/config.md +++ b/docs/config.md @@ -189,6 +189,7 @@ Attribute | Description | Default `igmp-autostart` | Optionally overwrite IGMP autostart per access configuration `igmp-version` | Optionally overwrite IGMP protocol version (1, 2 or 3) per access configuration `stream-group-id` | Optional stream group identifier +`access-line-profile-id` | Optional access-line-profile identifier `cfm-cc` | Optionally enable/disable EOAM CFM CC (IPoE only) | false `cfm-level` | Set EOAM CFM maintenance domain level | 0 `cfm-ma-id` | Set EOAM CFM maintenance association identifier | 0 @@ -450,18 +451,6 @@ Attribute | Description | Default `conf-request-timeout` | IP6CP configuration request timeout in seconds | 5 `conf-request-retry` | IP6CP configuration request max retry | 10 -## Access-Line - -This section describes all attributes of the `access-line` hierarchy. - -Attribute | Description | Default ---------- | ----------- | ------- -`agent-circuit-id` | Agent-Circuit-Id | 0.0.0.0/0.0.0.0 eth 0:{session-global} -`agent-remote-id` | Agent-Remote-Id | DEU.RTBRICK.{session-global} -`rate-up` | Actual-Data-Rate-Upstream | 0 -`rate-down` | Actual-Data-Rate-Downstream | 0 -`dsl-type` | DSL-Type | 0 - ## DHCP This section describes all attributes of the `dhcp` hierarchy. @@ -612,3 +601,108 @@ For L2TP downstream traffic the IPv4 TOS is applied to the outer IPv4 and inner The `pps` option has priority over `bps` where second is only a helper to calculate the `pps` based on given `bps` and `length`. + +## Access-Line + +This section describes all attributes of the `access-line` hierarchy. + +Attribute | Description | Default +--------- | ----------- | ------- +`agent-circuit-id` | Agent-Circuit-Id | 0.0.0.0/0.0.0.0 eth 0:{session-global} +`agent-remote-id` | Agent-Remote-Id | DEU.RTBRICK.{session-global} +`rate-up` | Actual Data Rate Upstream | 0 +`rate-down` | Actual Data Rate Downstream | 0 +`dsl-type` | DSL-Type | 0 + +## Access-Line-Profiles + +This section describes all attributes of the `access-line-profiles` hierarchy +as explained in [Traffic Streams](streams). + +Attribute | Description | Default +--------- | ----------- | ------- + +`access-line-profile-id` | Mandatory access-line-profile identifier | +`act-up` | Actual Data Rate Upstream | 0 +`act-down` | Actual Data Rate Downstream | 0 +`min-up` | Minimum Data Rate Upstream | 0 +`min-down` | Minimum Data Rate Downstream | 0 +`att-up` | Attainable DataRate Upstream | 0 +`att-down` | Attainable DataRate Downstream | 0 +`max-up` | Maximum Data Rate Upstream | 0 +`max-down` | Maximum Data Rate Downstream | 0 +`min-up-low` | Min Data Rate Upstream in low power state | 0 +`min-down-low` | Min Data Rate Downstream in low power state | 0 +`max-interl-delay-up` | Max Interleaving Delay Upstream | 0 +`act-interl-delay-up` | Actual Interleaving Delay Upstream | 0 +`max-interl-delay-down` | Max Interleaving Delay Downstream | 0 +`act-interl-delay-down` | Actual Interleaving Delay Downstream | 0 +`data-link-encaps` | Data Link Encapsulation | 0 +`dsl-type` | DSL Type | 0 +`pon-type` | PON Access Type | 0 +`etr-up` | Expected Throughput (ETR) Upstream | 0 +`etr-down` | Expected Throughput (ETR) Downstream | 0 +`attetr-up` | Attainable Expected Throughput (ATTETR) Upstream | 0 +`attetr-down` | Attainable Expected Throughput (ATTETR) Downstream | 0 +`gdr-up` | Gamma Data Rate (GDR) Upstream | 0 +`gdr-down` | Gamma Data Rate (GDR) Downstream | 0 +`attgdr-up` | Attainable Gamma Data Rate (ATTGDR) Upstream | 0 +`attgdr-down` | Attainable Gamma Data Rate (ATTGDR) Downstream | 0 +`ont-onu-avg-down` | ONT/ONU Average Data Rate Downstream | 0 +`ont-onu-peak-down` | ONT/ONUPeak Data Rate Downstream | 0 +`ont-onu-max-up` | ONT/ONU Maximum Data Rate Upstream | 0 +`ont-onu-ass-up` | ONT/ONU Assured Data Rate Upstream | 0 +`pon-max-up` | PON Tree Maximum Data Rate Upstream | 0 +`pon-max-down` | PON Tree Maximum Data Rate Downstream | 0 + +Attributes with value set to 0 will not be send. + +The values for `rate-up`, `rate-down` and `dsl-type` defined in the +access-line or interface section have priority over those defined +here. + +```json +{ + "access-line-profiles": [ + { + "access-line-profile-id": 1, + "act-up": 2000, + "act-down": 16000, + "min-up": 64, + "min-down": 1024, + "att-up": 2048, + "att-down": 16384, + "max-up": 2040, + "max-down": 16380, + "min-up-low": 32, + "min-down-low": 1024, + "max-interl-delay-up": 100, + "act-interl-delay-up": 10, + "max-interl-delay-down": 100, + "act-interl-delay-down": 10, + "data-link-encaps": 525061, + "dsl-type": 5, + }, + { + "access-line-profile-id": 2, + "act-up": 40000, + "act-down": 100000, + "pon-type": 1, + "etr-up": 40000, + "etr-down": 100000, + "attetr-up": 40000, + "attetr-down": 100000, + "gdr-up": 40000, + "gdr-down": 100000, + "attgdr-up": 40000, + "attgdr-down": 100000, + "ont-onu-avg-down": 100000, + "ont-onu-peak-down": 100000, + "ont-onu-max-up": 40000, + "ont-onu-ass-up": 40000, + "pon-max-up": 1000000, + "pon-max-down": 2400000 + } + ] +} +``` \ No newline at end of file diff --git a/src/bbl.h b/src/bbl.h index 0ef557a0..c7b8a569 100644 --- a/src/bbl.h +++ b/src/bbl.h @@ -382,6 +382,8 @@ typedef struct bbl_access_config_ uint32_t rate_down; uint32_t dsl_type; + uint16_t access_line_profile_id; + /* Protocols */ bool ipcp_enable; bool ip6cp_enable; @@ -408,6 +410,50 @@ typedef struct bbl_access_config_ void *next; /* pointer to next access config element */ } bbl_access_config_s; +typedef struct bbl_access_line_profile_ +{ + uint16_t access_line_profile_id; + + // broadband forum tr101 + + uint32_t act_up; /* Actual Data Rate Upstream */ + uint32_t act_down; /* Actual Data Rate Downstream */ + uint32_t min_up; /* Minimum Data Rate Upstream */ + uint32_t min_down; /* Minimum Data Rate Downstream */ + uint32_t att_up; /* Attainable DataRate Upstream */ + uint32_t att_down; /* Attainable DataRate Downstream */ + uint32_t max_up; /* Maximum Data Rate Upstream */ + uint32_t max_down; /* Maximum Data Rate Downstream */ + uint32_t min_up_low; /* Min Data Rate Upstream in low power state */ + uint32_t min_down_low; /* Min Data Rate Downstream in low power state */ + uint32_t max_interl_delay_up; /* Max Interleaving Delay Upstream */ + uint32_t act_interl_delay_up; /* Actual Interleaving Delay Upstream */ + uint32_t max_interl_delay_down; /* Max Interleaving Delay Downstream */ + uint32_t act_interl_delay_down; /* Actual Interleaving Delay Downstream */ + uint32_t data_link_encaps; /* Data Link Encapsulation */ + uint32_t dsl_type; /* DSL Type */ + + // draft-lihawi-ancp-protocol-access-extension-04 + + uint32_t pon_type; /* PON-Access-Type */ + uint32_t etr_up; /* Expected Throughput (ETR) Upstream */ + uint32_t etr_down; /* Expected Throughput (ETR) Downstream */ + uint32_t attetr_up; /* Attainable Expected Throughput (ATTETR) Upstream */ + uint32_t attetr_down; /* Attainable Expected Throughput (ATTETR) Downstream */ + uint32_t gdr_up; /* Gamma Data Rate (GDR) Upstream */ + uint32_t gdr_down; /* Gamma Data Rate (GDR) Downstream */ + uint32_t attgdr_up; /* Attainable Gamma Data Rate (ATTGDR) Upstream */ + uint32_t attgdr_down; /* Attainable Gamma Data Rate (ATTGDR) Downstream */ + uint32_t ont_onu_avg_down; /* ONT/ONU-Average-Data-Rate-Downstream */ + uint32_t ont_onu_peak_down; /* ONT/ONU-Peak-Data-Rate-Downstream */ + uint32_t ont_onu_max_up; /* ONT/ONU-Maximum-Data-Rate-Upstream */ + uint32_t ont_onu_ass_up; /* ONT/ONU-Assured-Data-Rate-Upstream */ + uint32_t pon_max_up; /* PON-Tree-Maximum-Data-Rate-Upstream */ + uint32_t pon_max_down; /* PON-Tree-Maximum-Data-Rate-Downstream */ + + void *next; /* pointer to next access line profile element */ +} bbl_access_line_profile_s; + /* * BBL context. Top level data structure. */ @@ -532,6 +578,9 @@ typedef struct bbl_ctx_ /* Access Interfaces */ bbl_access_config_s *access_config; + /* Access Line Profiles */ + void *access_line_profile; + /* Traffic Streams */ void *stream_config; @@ -794,6 +843,8 @@ typedef struct bbl_session_ uint32_t rate_down; uint32_t dsl_type; + void *access_line_profile; + /* Ethernet */ uint8_t server_mac[ETH_ADDR_LEN]; uint8_t client_mac[ETH_ADDR_LEN]; diff --git a/src/bbl_config.c b/src/bbl_config.c index 1ba5d4e6..a94c8dd1 100644 --- a/src/bbl_config.c +++ b/src/bbl_config.c @@ -87,6 +87,138 @@ add_secondary_ipv6(bbl_ctx_s *ctx, ipv6addr_t ipv6) { } } +static bool +json_parse_access_line_profile (json_t *config, bbl_access_line_profile_s *profile) { + json_t *value = NULL; + + value = json_object_get(config, "access-line-profile-id"); + if (value) { + profile->access_line_profile_id = json_number_value(value); + } else { + fprintf(stderr, "Config error: Missing value for access-line-profiles->access-line-profile-id\n"); + return false; + } + + value = json_object_get(config, "act-up"); + if (value) { + profile->act_up = json_number_value(value); + } + value = json_object_get(config, "act-down"); + if (value) { + profile->act_down = json_number_value(value); + } + value = json_object_get(config, "min-up"); + if (value) { + profile->min_up = json_number_value(value); + } + value = json_object_get(config, "min-down"); + if (value) { + profile->min_down = json_number_value(value); + } + value = json_object_get(config, "att-up"); + if (value) { + profile->att_up = json_number_value(value); + } + value = json_object_get(config, "att-down"); + if (value) { + profile->att_down = json_number_value(value); + } + value = json_object_get(config, "min-up-low"); + if (value) { + profile->min_up_low = json_number_value(value); + } + value = json_object_get(config, "min-down-low"); + if (value) { + profile->min_down_low = json_number_value(value); + } + value = json_object_get(config, "max-interl-delay-up"); + if (value) { + profile->max_interl_delay_up = json_number_value(value); + } + value = json_object_get(config, "act-interl-delay-up"); + if (value) { + profile->act_interl_delay_up = json_number_value(value); + } + value = json_object_get(config, "max-interl-delay-down"); + if (value) { + profile->max_interl_delay_down = json_number_value(value); + } + value = json_object_get(config, "act-interl-delay-down"); + if (value) { + profile->act_interl_delay_down = json_number_value(value); + } + value = json_object_get(config, "data-link-encaps"); + if (value) { + profile->data_link_encaps = json_number_value(value); + } + value = json_object_get(config, "dsl-type"); + if (value) { + profile->dsl_type = json_number_value(value); + } + value = json_object_get(config, "pon-type"); + if (value) { + profile->pon_type = json_number_value(value); + } + value = json_object_get(config, "etr-up"); + if (value) { + profile->etr_up = json_number_value(value); + } + value = json_object_get(config, "etr-down"); + if (value) { + profile->etr_down = json_number_value(value); + } + value = json_object_get(config, "attetr-up"); + if (value) { + profile->attetr_up = json_number_value(value); + } + value = json_object_get(config, "attetr-down"); + if (value) { + profile->attetr_down = json_number_value(value); + } + value = json_object_get(config, "gdr-up"); + if (value) { + profile->gdr_up = json_number_value(value); + } + value = json_object_get(config, "gdr-down"); + if (value) { + profile->gdr_down = json_number_value(value); + } + value = json_object_get(config, "attgdr-up"); + if (value) { + profile->attgdr_up = json_number_value(value); + } + value = json_object_get(config, "attgdr-down"); + if (value) { + profile->attgdr_down = json_number_value(value); + } + value = json_object_get(config, "ont-onu-avg-down"); + if (value) { + profile->ont_onu_avg_down = json_number_value(value); + } + value = json_object_get(config, "ont-onu-peak-down"); + if (value) { + profile->ont_onu_peak_down = json_number_value(value); + } + value = json_object_get(config, "ont-onu-max-up"); + if (value) { + profile->ont_onu_max_up = json_number_value(value); + } + value = json_object_get(config, "ont-onu-ass-up"); + if (value) { + profile->ont_onu_ass_up = json_number_value(value); + } + value = json_object_get(config, "pon-max-up"); + if (value) { + profile->pon_max_up = json_number_value(value); + } + value = json_object_get(config, "pon-max-down"); + if (value) { + profile->pon_max_down = json_number_value(value); + } + + return true; +} + static bool json_parse_access_interface (bbl_ctx_s *ctx, json_t *access_interface, bbl_access_config_s *access_config) { json_t *value = NULL; @@ -283,6 +415,11 @@ json_parse_access_interface (bbl_ctx_s *ctx, json_t *access_interface, bbl_acces access_config->dsl_type = ctx->config.dsl_type; } + value = json_object_get(access_interface, "access-line-profile-id"); + if (value) { + access_config->access_line_profile_id = json_number_value(value); + } + value = json_object_get(access_interface, "ipcp"); if (json_is_boolean(value)) { access_config->ipcp_enable = json_boolean_value(value); @@ -534,9 +671,10 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) { const char *s; uint32_t ipv4; int i, size; - bbl_access_config_s *access_config = NULL; - bbl_stream_config *stream_config = NULL; - bbl_l2tp_server_t *l2tp_server = NULL; + bbl_access_config_s *access_config = NULL; + bbl_access_line_profile_s *access_line_profile = NULL; + bbl_stream_config *stream_config = NULL; + bbl_l2tp_server_t *l2tp_server = NULL; if(json_typeof(root) != JSON_OBJECT) { fprintf(stderr, "JSON config error: Configuration root element must object\n"); @@ -1164,6 +1302,26 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) { } } + /* Access Line Profiles Configuration */ + section = json_object_get(root, "access-line-profiles"); + if (json_is_array(section)) { + /* Config is provided as array (multiple access-line-profiles) */ + size = json_array_size(section); + for (i = 0; i < size; i++) { + if(!access_line_profile) { + ctx->config.access_line_profile = malloc(sizeof(bbl_access_line_profile_s)); + access_line_profile = ctx->config.access_line_profile; + } else { + access_line_profile->next = malloc(sizeof(bbl_access_line_profile_s)); + access_line_profile = access_line_profile->next; + } + memset(access_line_profile, 0x0, sizeof(bbl_access_line_profile_s)); + if(!json_parse_access_line_profile(json_array_get(section, i), access_line_profile)) { + return false; + } + } + } + return true; } diff --git a/src/bbl_protocols.c b/src/bbl_protocols.c index f64c07b3..23f8b981 100644 --- a/src/bbl_protocols.c +++ b/src/bbl_protocols.c @@ -6,6 +6,7 @@ * Copyright (C) 2020-2021, RtBrick, Inc. * SPDX-License-Identifier: BSD-3-Clause */ +#include "bbl.h" #include "bbl_protocols.h" protocol_error_t decode_l2tp(uint8_t *buf, uint16_t len, uint8_t *sp, uint16_t sp_len, bbl_l2tp_t **_l2tp); @@ -1255,6 +1256,8 @@ encode_pppoe_discovery(uint8_t *buf, uint16_t *len, uint16_t vendor_len; uint8_t str_len; + bbl_access_line_profile_s *access_line_profile; + /* Set version and type to 1 */ *buf = 17; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); @@ -1300,6 +1303,8 @@ encode_pppoe_discovery(uint8_t *buf, uint16_t *len, pppoe_len += pppoe->ac_cookie_len; } if(pppoe->access_line) { + access_line_profile = pppoe->access_line->profile; + *(uint16_t*)buf = htobe16(PPPOE_TAG_VENDOR); BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); vendor_len_field = (uint16_t*)buf; @@ -1327,30 +1332,304 @@ encode_pppoe_discovery(uint8_t *buf, uint16_t *len, BUMP_WRITE_BUFFER(buf, len, str_len); vendor_len += 2 + str_len; } - if(pppoe->access_line->up) { + if(pppoe->access_line->up || (access_line_profile && access_line_profile->act_up)) { *buf = ACCESS_LINE_ACT_UP; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); *buf = 4; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); - *(uint32_t*)buf = htobe32(pppoe->access_line->up); + if(pppoe->access_line->up) { + *(uint32_t*)buf = htobe32(pppoe->access_line->up); + } else { + *(uint32_t*)buf = htobe32(access_line_profile->act_up); + } BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); vendor_len += 6; } - if(pppoe->access_line->down) { + if(pppoe->access_line->down || (access_line_profile && access_line_profile->act_down)) { *buf = ACCESS_LINE_ACT_DOWN; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); *buf = 4; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); - *(uint32_t*)buf = htobe32(pppoe->access_line->down); + if(pppoe->access_line->down) { + *(uint32_t*)buf = htobe32(pppoe->access_line->down); + } else { + *(uint32_t*)buf = htobe32(access_line_profile->act_down); + } BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); vendor_len += 6; } - if(pppoe->access_line->down) { + if(pppoe->access_line->dsl_type || (access_line_profile && access_line_profile->dsl_type)) { *buf = ACCESS_LINE_DSL_TYPE; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); *buf = 4; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); - *(uint32_t*)buf = htobe32(pppoe->access_line->dsl_type); + if(pppoe->access_line->dsl_type) { + *(uint32_t*)buf = htobe32(pppoe->access_line->dsl_type); + } else { + *(uint32_t*)buf = htobe32(access_line_profile->dsl_type); + } + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->min_up) { + *buf = ACCESS_LINE_MIN_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->min_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->min_down) { + *buf = ACCESS_LINE_MIN_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->min_down); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->att_up) { + *buf = ACCESS_LINE_ATT_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->att_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->att_down) { + *buf = ACCESS_LINE_ATT_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->att_down); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->max_up) { + *buf = ACCESS_LINE_MAX_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->max_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->max_down) { + *buf = ACCESS_LINE_MAX_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->max_down); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->min_up_low) { + *buf = ACCESS_LINE_MIN_UP_LOW; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->min_up_low); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->min_down_low) { + *buf = ACCESS_LINE_MIN_DOWN_LOW; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->min_down_low); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->max_interl_delay_up) { + *buf = ACCESS_LINE_MAX_INTERL_DELAY_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->max_interl_delay_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->act_interl_delay_up) { + *buf = ACCESS_LINE_ACT_INTERL_DELAY_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->act_interl_delay_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->max_interl_delay_down) { + *buf = ACCESS_LINE_MAX_INTERL_DELAY_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->max_interl_delay_down); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->act_interl_delay_down) { + *buf = ACCESS_LINE_ACT_INTERL_DELAY_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->act_interl_delay_down); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->data_link_encaps) { + *buf = ACCESS_LINE_DATA_LINK_ENCAPS; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + /* (1)byte + (1)byte + (1)byte + * data link encaps 1 encaps 2 */; + *(uint32_t*)buf = htobe32(access_line_profile->data_link_encaps); + *buf = 3; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 5; + } + if(access_line_profile && access_line_profile->dsl_type) { + *buf = ACCESS_LINE_DSL_TYPE; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->dsl_type); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->pon_type) { + *buf = ACCESS_LINE_PON_TYPE; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->pon_type); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->etr_up) { + *buf = ACCESS_LINE_ETR_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->etr_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->etr_down) { + *buf = ACCESS_LINE_ETR_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->etr_down); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->attetr_up) { + *buf = ACCESS_LINE_ATTETR_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->attetr_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->attetr_down) { + *buf = ACCESS_LINE_ATTETR_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->attetr_down); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->gdr_up) { + *buf = ACCESS_LINE_GDR_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->gdr_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->gdr_down) { + *buf = ACCESS_LINE_GDR_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->gdr_down); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->attgdr_up) { + *buf = ACCESS_LINE_ATTGDR_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->attgdr_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->attgdr_down) { + *buf = ACCESS_LINE_ATTGDR_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->attgdr_down); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->ont_onu_avg_down) { + *buf = ACCESS_LINE_ONT_ONU_AVG_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->ont_onu_avg_down); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->ont_onu_peak_down) { + *buf = ACCESS_LINE_ONT_ONU_PEAK_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->ont_onu_peak_down); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->ont_onu_max_up) { + *buf = ACCESS_LINE_ONT_ONU_MAX_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->ont_onu_max_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->ont_onu_ass_up) { + *buf = ACCESS_LINE_ONT_ONU_ASS_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->ont_onu_ass_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->pon_max_up) { + *buf = ACCESS_LINE_PON_MAX_UP; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->pon_max_up); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + vendor_len += 6; + } + if(access_line_profile && access_line_profile->pon_max_down) { + *buf = ACCESS_LINE_PON_MAX_DOWN; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *buf = 4; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + *(uint32_t*)buf = htobe32(access_line_profile->pon_max_down); BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); vendor_len += 6; } diff --git a/src/bbl_protocols.h b/src/bbl_protocols.h index d9fec6b9..91bd2ea0 100644 --- a/src/bbl_protocols.h +++ b/src/bbl_protocols.h @@ -420,8 +420,8 @@ typedef enum access_line_codes_ { // broadband forum tr101 ACCESS_LINE_ACI = 0x01, // Agent Circuit ID ACCESS_LINE_ARI = 0x02, // Agent Remote ID - ACCESS_AGG_ACC_CIRCUIT_ID_ASCII = 0x03, // Access-Aggregation-Circuit-ID-ASCII - ACCESS_AGG_ACC_CIRCUIT_ID_BIN = 0x06, // Access-Aggregation-Circuit-ID-ASCII + ACCESS_LINE_AGG_ACC_CIRCUIT_ID_ASCII = 0x03, // Access-Aggregation-Circuit-ID-ASCII + ACCESS_LINE_AGG_ACC_CIRCUIT_ID_BIN = 0x06, // Access-Aggregation-Circuit-ID-BINARY ACCESS_LINE_ACT_UP = 0x81, // Actual Data Rate Upstream ACCESS_LINE_ACT_DOWN = 0x82, // Actual Data Rate Downstream ACCESS_LINE_MIN_UP = 0x83, // Minimum Data Rate Upstream @@ -462,6 +462,7 @@ typedef struct access_line_ { uint32_t up; // Actual Data Rate Upstream uint32_t down; // Actual Data Rate Downstream uint32_t dsl_type; // DSL Type + void *profile; } access_line_t; /* diff --git a/src/bbl_session.c b/src/bbl_session.c index accee249..52176462 100644 --- a/src/bbl_session.c +++ b/src/bbl_session.c @@ -373,7 +373,7 @@ bbl_sessions_init(bbl_ctx_s *ctx) { bbl_session_s *session; bbl_access_config_s *access_config; - + bbl_access_line_profile_s *access_line_profile; dict_insert_result result; uint32_t i = 1; /* BNG Blaster internal session identifier */ @@ -565,6 +565,18 @@ bbl_sessions_init(bbl_ctx_s *ctx) } timer_add_periodic(&ctx->timer_root, &session->timer_rate, "Rate Computation", 1, 0, session, &bbl_session_rate_job); } + + if(access_config->access_line_profile_id) { + access_line_profile = ctx->config.access_line_profile; + while(access_line_profile) { + if(access_line_profile->access_line_profile_id == access_config->access_line_profile_id) { + session->access_line_profile = access_line_profile; + break; + } + access_line_profile = access_line_profile->next; + } + } + LOG(DEBUG, "Session %u created (%s.%u:%u)\n", i, access_config->interface, access_config->access_outer_vlan, access_config->access_inner_vlan); i++; NEXT: diff --git a/src/bbl_tx.c b/src/bbl_tx.c index f631ef47..576295bb 100644 --- a/src/bbl_tx.c +++ b/src/bbl_tx.c @@ -1144,6 +1144,7 @@ bbl_encode_padi (bbl_session_s *session) access_line.up = session->rate_up; access_line.down = session->rate_down; access_line.dsl_type = session->dsl_type; + access_line.profile = session->access_line_profile; pppoe.access_line = &access_line; } return encode_ethernet(session->write_buf, &session->write_idx, ð); @@ -1188,6 +1189,7 @@ bbl_encode_padr (bbl_session_s *session) access_line.up = session->rate_up; access_line.down = session->rate_down; access_line.dsl_type = session->dsl_type; + access_line.profile = session->access_line_profile; pppoe.access_line = &access_line; } return encode_ethernet(session->write_buf, &session->write_idx, ð);