diff --git a/PPPOE_SETUP.md b/PPPOE_SETUP.md new file mode 100644 index 0000000..e77948c --- /dev/null +++ b/PPPOE_SETUP.md @@ -0,0 +1,182 @@ +# MikroTik PPPoE to CGRateS RADIUS Integration + +## Architecture Overview + +``` +┌─────────────────────┐ RADIUS (UDP 1812/1813) ┌──────────────────┐ +│ MikroTik Router │ ◄─────────────────────────────────────► │ CGRateS │ +│ (PPPoE Server) │ │ RADIUS Agent │ +└─────────────────────┘ └──────────────────┘ + │ │ + │ PPPoE │ + ▼ ▼ +┌─────────────────────┐ ┌──────────────────┐ +│ PPPoE Clients │ │ Redis (Data) │ +│ (Subscribers) │ │ MySQL (CDRs) │ +└─────────────────────┘ └──────────────────┘ +``` + +## CGRateS Configuration Files + +| File | Description | +|------|-------------| +| `cgrates.json` | Main CGRateS configuration | +| `pppoe_auth.json` | PPPoE authentication request processors | +| `pppoe_accounting.json` | PPPoE accounting request processors | +| `tariffplans/pppoe/` | Tariff plan data (users, rates, balances) | + +## MikroTik Configuration + +### 1. Add RADIUS Server + +```routeros +/radius +add address= secret=CGRateS.org service=ppp timeout=3s +``` + +### 2. Configure PPPoE Server Profile + +```routeros +/ppp profile +add name=pppoe-profile use-radius=yes only-one=yes \ + rate-limit="" \ + incoming-filter="" outgoing-filter="" \ + local-address=10.0.0.1 \ + dns-server=8.8.8.8,8.8.4.4 +``` + +### 3. Configure PPPoE Server + +```routeros +/interface pppoe-server server +add service-name=pppoe-service interface=ether1 \ + default-profile=pppoe-profile \ + authentication=pap,chap,mschap2 \ + one-session-per-host=yes +``` + +### 4. Enable RADIUS for PPP + +```routeros +/ppp aaa +set use-radius=yes accounting=yes interim-update=1m +``` + +### 5. (Optional) Configure RADIUS Incoming (CoA/Disconnect) + +```routeros +/radius incoming +set accept=yes port=3799 +``` + +## CGRateS Setup Commands + +### 1. Start Redis + +```bash +redis-server +``` + +### 2. Start CGRateS Engine + +```bash +cgr-engine -config_path=/path/to/cgrates-radius/ +``` + +### 3. Load Tariff Plan + +```bash +cgr-loader -config_path=/path/to/cgrates-radius/ \ + -path=/path/to/cgrates-radius/tariffplans/pppoe/ \ + -verbose +``` + +## Sample PPPoE Users + +| Username | Password | Static IP | Rate Limit | Balance | +|----------|----------|-----------|------------|---------| +| pppoe_user1 | SecurePass123 | 10.0.0.101 | 10M/10M | 100 units | +| pppoe_user2 | SecurePass456 | 10.0.0.102 | 20M/20M | 100 units | +| pppoe_user3 | SecurePass789 | Dynamic | 50M/50M | 100 units | + +## Authentication Flow + +1. **Client connects** → MikroTik sends Access-Request to CGRateS +2. **CGRateS processes** → `MikrotikPPPoEAuthCGR` extracts user info, checks balance +3. **Password validation** → `MikrotikPPPoEAuthPAP/CHAP/MSCHAPv2` validates credentials +4. **Access-Accept** → Returns Session-Timeout, Framed-IP-Address, Mikrotik-Rate-Limit +5. **Session starts** → MikroTik assigns IP and rate limit to client + +## Accounting Flow + +1. **Session starts** → `MikrotikPPPoEAcctStart` initiates session in CGRateS +2. **Interim updates** → `MikrotikPPPoEAcctInterim` updates usage every 60 seconds +3. **Session ends** → `MikrotikPPPoEAcctStop` terminates session, generates CDR + +## RADIUS Attributes + +### Authentication Request (from MikroTik) +- User-Name +- User-Password / CHAP-Password / MS-CHAP-Challenge +- NAS-IP-Address +- NAS-Port-Type +- Calling-Station-Id (MAC) +- Acct-Session-Id + +### Authentication Reply (from CGRateS) +- Session-Timeout +- Acct-Interim-Interval +- Framed-IP-Address +- Framed-IP-Netmask +- Mikrotik-Rate-Limit + +### Accounting Request (from MikroTik) +- Acct-Status-Type (Start/Interim-Update/Stop) +- Acct-Session-Id +- Acct-Session-Time +- Acct-Input-Octets +- Acct-Output-Octets +- User-Name +- NAS-IP-Address +- Framed-IP-Address + +## Testing + +### Test Authentication with radtest + +```bash +radtest pppoe_user1 SecurePass123 localhost 1812 CGRateS.org +``` + +### Check Active Sessions + +```bash +cgr-console 'sessions_get_active_sessions' +``` + +### Check Account Balance + +```bash +cgr-console 'accounts Tenant="cgrates.org" Account="pppoe_user1"' +``` + +## Troubleshooting + +### Enable CGRateS Debug Logging +Set `"log_level": 7` in cgrates.json + +### Check RADIUS Traffic on MikroTik +```routeros +/tool sniffer +quick ip-protocol=udp port=1812-1813 +``` + +### Verify RADIUS Secret +Ensure `secret=CGRateS.org` matches `client_secrets` in cgrates.json + +## Notes + +- **Shared Secret**: Default is `CGRateS.org` - change in production! +- **Rate Limit Format**: MikroTik uses `rx/tx` format (e.g., `10M/10M`) +- **Session-Timeout**: Returned in seconds based on prepaid balance +- **Interim Interval**: Set to 60 seconds for frequent balance updates diff --git a/cgrates.json b/cgrates.json index be254bd..7914cdc 100644 --- a/cgrates.json +++ b/cgrates.json @@ -72,13 +72,14 @@ "network": "udp", "auth_address": "0.0.0.0:1812", "acct_address": "0.0.0.0:1813" - }, - { - "network": "tcp", - "auth_address": "0.0.0.0:1812", - "acct_address": "0.0.0.0:1813" - }, - ], + } + ], + "client_secrets": { + "*default": "CGRateS.org" + }, + "client_dictionaries": { + "*default": ["/usr/share/cgrates/radius/dict/"] + } }, diff --git a/pppoe_accounting.json b/pppoe_accounting.json new file mode 100644 index 0000000..f9c4040 --- /dev/null +++ b/pppoe_accounting.json @@ -0,0 +1,104 @@ +{ + "radius_agent": { + "request_processors": [ + { + "id": "MikrotikPPPoEAcctStart", + "filters": ["*string:~*req.Acct-Status-Type:Start"], + "flags": ["*initiate", "*attributes", "*resources", "*accounts"], + "request_fields": [ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*data"}, + {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "generic"}, + {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", + "value": "*prepaid", "mandatory": true}, + {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", + "value": "~*req.Acct-Session-Id", "mandatory": true}, + {"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*variable", + "value": "~*req.NAS-IP-Address", "mandatory": true}, + {"tag": "Account", "path": "*cgreq.Account", "type": "*variable", + "value": "~*req.User-Name", "mandatory": true}, + {"tag": "Subject", "path": "*cgreq.Subject", "type": "*variable", + "value": "~*req.User-Name", "mandatory": true}, + {"tag": "Destination", "path": "*cgreq.Destination", "type": "*constant", + "value": "data"}, + {"tag": "SetupTime", "path": "*cgreq.SetupTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "CallingStationId", "path": "*cgreq.CallingStationId", "type": "*variable", + "value": "~*req.Calling-Station-Id"}, + {"tag": "FramedIPAddress", "path": "*cgreq.FramedIPAddress", "type": "*variable", + "value": "~*req.Framed-IP-Address"}, + {"tag": "RemoteAddr", "path": "*cgreq.RemoteAddr", "type": "*variable", + "value": "~*vars.RemoteHost:s/(.*):\\d+/${1}/"} + ], + "reply_fields": [] + }, + { + "id": "MikrotikPPPoEAcctInterim", + "filters": ["*string:~*req.Acct-Status-Type:Interim-Update"], + "flags": ["*update", "*accounts"], + "request_fields": [ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*data"}, + {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "generic"}, + {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", + "value": "*prepaid", "mandatory": true}, + {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", + "value": "~*req.Acct-Session-Id", "mandatory": true}, + {"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*variable", + "value": "~*req.NAS-IP-Address", "mandatory": true}, + {"tag": "Account", "path": "*cgreq.Account", "type": "*variable", + "value": "~*req.User-Name", "mandatory": true}, + {"tag": "Subject", "path": "*cgreq.Subject", "type": "*variable", + "value": "~*req.User-Name", "mandatory": true}, + {"tag": "Destination", "path": "*cgreq.Destination", "type": "*constant", + "value": "data"}, + {"tag": "SetupTime", "path": "*cgreq.SetupTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "Usage", "path": "*cgreq.Usage", "type": "*variable", + "value": "~*req.Acct-Session-Time{*duration_seconds}"}, + {"tag": "LastUsed", "path": "*cgreq.LastUsed", "type": "*sum", + "value": "~*req.Acct-Input-Octets;~*req.Acct-Output-Octets"} + ], + "reply_fields": [] + }, + { + "id": "MikrotikPPPoEAcctStop", + "filters": ["*string:~*req.Acct-Status-Type:Stop"], + "flags": ["*terminate", "*resources", "*accounts", "*cdrs"], + "request_fields": [ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*data"}, + {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "generic"}, + {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", + "value": "*prepaid", "mandatory": true}, + {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", + "value": "~*req.Acct-Session-Id", "mandatory": true}, + {"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*variable", + "value": "~*req.NAS-IP-Address", "mandatory": true}, + {"tag": "Account", "path": "*cgreq.Account", "type": "*variable", + "value": "~*req.User-Name", "mandatory": true}, + {"tag": "Subject", "path": "*cgreq.Subject", "type": "*variable", + "value": "~*req.User-Name", "mandatory": true}, + {"tag": "Destination", "path": "*cgreq.Destination", "type": "*constant", + "value": "data"}, + {"tag": "SetupTime", "path": "*cgreq.SetupTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "Usage", "path": "*cgreq.Usage", "type": "*variable", + "value": "~*req.Acct-Session-Time{*duration_seconds}", "mandatory": true}, + {"tag": "DataUsed", "path": "*cgreq.DataUsed", "type": "*sum", + "value": "~*req.Acct-Input-Octets;~*req.Acct-Output-Octets"}, + {"tag": "CallingStationId", "path": "*cgreq.CallingStationId", "type": "*variable", + "value": "~*req.Calling-Station-Id"}, + {"tag": "FramedIPAddress", "path": "*cgreq.FramedIPAddress", "type": "*variable", + "value": "~*req.Framed-IP-Address"}, + {"tag": "RemoteAddr", "path": "*cgreq.RemoteAddr", "type": "*variable", + "value": "~*vars.RemoteHost:s/(.*):\\d+/${1}/"} + ], + "reply_fields": [] + } + ] + } +} diff --git a/pppoe_auth.json b/pppoe_auth.json new file mode 100644 index 0000000..0d4afeb --- /dev/null +++ b/pppoe_auth.json @@ -0,0 +1,109 @@ +{ + "radius_agent": { + "request_processors": [ + { + "id": "MikrotikPPPoEAuthCGR", + "filters": [ + "*string:~*vars.*radReqType:*radAuth" + ], + "flags": ["*authorize", "*attributes", "*accounts", "*continue"], + "request_fields": [ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*data"}, + {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "generic"}, + {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", + "value": "*prepaid", "mandatory": true}, + {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", + "value": "~*req.Acct-Session-Id", "mandatory": true}, + {"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*variable", + "value": "~*req.NAS-IP-Address", "mandatory": true}, + {"tag": "Account", "path": "*cgreq.Account", "type": "*variable", + "value": "~*req.User-Name", "mandatory": true}, + {"tag": "Subject", "path": "*cgreq.Subject", "type": "*variable", + "value": "~*req.User-Name", "mandatory": true}, + {"tag": "Destination", "path": "*cgreq.Destination", "type": "*constant", + "value": "data"}, + {"tag": "SetupTime", "path": "*cgreq.SetupTime", "type": "*variable", + "value": "~*req.Event-Timestamp"}, + {"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*variable", + "value": "~*req.Event-Timestamp"}, + {"tag": "CallingStationId", "path": "*cgreq.CallingStationId", "type": "*variable", + "value": "~*req.Calling-Station-Id"}, + {"tag": "PasswordFromAttributes", "path": "*cgreq.PasswordFromAttributes", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields": [ + {"tag": "SessionTimeout", "path": "*rep.Session-Timeout", "type": "*variable", + "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, + {"tag": "AcctInterimInterval", "path": "*rep.Acct-Interim-Interval", + "type": "*constant", "value": "60"}, + {"tag": "FramedIPAddress", "path": "*rep.Framed-IP-Address", "type": "*variable", + "value": "~*cgrep.Attributes.FramedIPAddress"}, + {"tag": "FramedIPNetmask", "path": "*rep.Framed-IP-Netmask", "type": "*variable", + "value": "~*cgrep.Attributes.FramedIPNetmask"}, + {"tag": "MikrotikRateLimit", "path": "*rep.Mikrotik-Rate-Limit", "type": "*variable", + "value": "~*cgrep.Attributes.MikrotikRateLimit"} + ] + }, + { + "id": "MikrotikPPPoEAuthPAP", + "filters": [ + "*string:~*vars.*radReqType:*radAuth", + "*notempty:~*req.User-Password:" + ], + "flags": ["*radauth", "*pap", "*log"], + "request_fields": [ + {"tag": "UserPassword", "path": "*vars.UserPassword", "type": "*variable", + "value": "~*cgrep.Attributes.PasswordFromAttributes"} + ], + "reply_fields": [ + {"tag": "RemoveAddedFields", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*removeall", "path": "*rep"}, + {"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*constant", "value": "AccessReject"}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*variable", "value": "~*cgrep.Error"} + ] + }, + { + "id": "MikrotikPPPoEAuthCHAP", + "filters": [ + "*string:~*vars.*radReqType:*radAuth", + "*notempty:~*req.CHAP-Password:" + ], + "flags": ["*radauth", "*chap", "*log"], + "request_fields": [ + {"tag": "UserPassword", "path": "*vars.UserPassword", "type": "*variable", + "value": "~*cgrep.Attributes.PasswordFromAttributes"} + ], + "reply_fields": [ + {"tag": "RemoveAddedFields", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*removeall", "path": "*rep"}, + {"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*constant", "value": "AccessReject"}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*variable", "value": "~*cgrep.Error"} + ] + }, + { + "id": "MikrotikPPPoEAuthMSCHAPv2", + "filters": [ + "*string:~*vars.*radReqType:*radAuth", + "*notempty:~*req.Microsoft.MS-CHAP-Challenge:" + ], + "flags": ["*radauth", "*mschapv2", "*log"], + "request_fields": [ + {"tag": "UserPassword", "path": "*vars.UserPassword", "type": "*variable", + "value": "~*cgrep.Attributes.PasswordFromAttributes"} + ], + "reply_fields": [ + {"tag": "RemoveAddedFields", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*removeall", "path": "*rep"}, + {"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*constant", "value": "AccessReject"}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*variable", "value": "~*cgrep.Error"} + ] + } + ] + } +} diff --git a/tariffplans/pppoe/AccountActions.csv b/tariffplans/pppoe/AccountActions.csv new file mode 100644 index 0000000..1d9fbd1 --- /dev/null +++ b/tariffplans/pppoe/AccountActions.csv @@ -0,0 +1,4 @@ +#Tenant,Account,ActionPlanId,ActionTriggersId,AllowNegative,Disabled +cgrates.org,pppoe_user1,AP_PPPOE_INIT,,, +cgrates.org,pppoe_user2,AP_PPPOE_INIT,,, +cgrates.org,pppoe_user3,AP_PPPOE_INIT,,, diff --git a/tariffplans/pppoe/ActionPlans.csv b/tariffplans/pppoe/ActionPlans.csv new file mode 100644 index 0000000..9d2c45d --- /dev/null +++ b/tariffplans/pppoe/ActionPlans.csv @@ -0,0 +1,5 @@ +#Id,ActionsId,TimingId,Weight +# Initial balance setup +AP_PPPOE_INIT,ACT_TOPUP_100,*asap,10 +# Monthly topup plan +AP_PPPOE_MONTHLY,ACT_TOPUP_1000,*monthly,10 diff --git a/tariffplans/pppoe/Actions.csv b/tariffplans/pppoe/Actions.csv new file mode 100644 index 0000000..439199f --- /dev/null +++ b/tariffplans/pppoe/Actions.csv @@ -0,0 +1,7 @@ +#ActionsId,Action,ExtraParameters,Filter,BalanceId,BalanceType,Categories,DestinationIds,RatingSubject,SharedGroup,ExpiryTime,TimingIds,Units,BalanceWeight,BalanceBlocker,BalanceDisabled,Weight +# Add 100 units of monetary balance (for prepaid users) +ACT_TOPUP_100,*topup_reset,,,main,*monetary,,,,,*unlimited,,100,10,false,false,10 +# Add 1000 units of monetary balance +ACT_TOPUP_1000,*topup_reset,,,main,*monetary,,,,,*unlimited,,1000,10,false,false,10 +# Log balance +ACT_LOG,*log,,,,,,,,,,,,,,,10 diff --git a/tariffplans/pppoe/Attributes.csv b/tariffplans/pppoe/Attributes.csv new file mode 100644 index 0000000..364569a --- /dev/null +++ b/tariffplans/pppoe/Attributes.csv @@ -0,0 +1,23 @@ +#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight +# PPPoE user credentials and RADIUS reply attributes +# User: pppoe_user1 - 10Mbps plan with static IP +cgrates.org,ATTR_PPPOE_USER1,*sessions,*string:~*req.Account:pppoe_user1,,,,,,false,20 +cgrates.org,ATTR_PPPOE_USER1,,,,,*req.Password,*constant,SecurePass123,, +cgrates.org,ATTR_PPPOE_USER1,,,,,*req.RequestType,*constant,*prepaid,, +cgrates.org,ATTR_PPPOE_USER1,,,,,*req.FramedIPAddress,*constant,10.0.0.101,, +cgrates.org,ATTR_PPPOE_USER1,,,,,*req.FramedIPNetmask,*constant,255.255.255.0,, +cgrates.org,ATTR_PPPOE_USER1,,,,,*req.MikrotikRateLimit,*constant,10M/10M,, + +# User: pppoe_user2 - 20Mbps plan with static IP +cgrates.org,ATTR_PPPOE_USER2,*sessions,*string:~*req.Account:pppoe_user2,,,,,,false,20 +cgrates.org,ATTR_PPPOE_USER2,,,,,*req.Password,*constant,SecurePass456,, +cgrates.org,ATTR_PPPOE_USER2,,,,,*req.RequestType,*constant,*prepaid,, +cgrates.org,ATTR_PPPOE_USER2,,,,,*req.FramedIPAddress,*constant,10.0.0.102,, +cgrates.org,ATTR_PPPOE_USER2,,,,,*req.FramedIPNetmask,*constant,255.255.255.0,, +cgrates.org,ATTR_PPPOE_USER2,,,,,*req.MikrotikRateLimit,*constant,20M/20M,, + +# User: pppoe_user3 - 50Mbps plan with dynamic IP +cgrates.org,ATTR_PPPOE_USER3,*sessions,*string:~*req.Account:pppoe_user3,,,,,,false,20 +cgrates.org,ATTR_PPPOE_USER3,,,,,*req.Password,*constant,SecurePass789,, +cgrates.org,ATTR_PPPOE_USER3,,,,,*req.RequestType,*constant,*prepaid,, +cgrates.org,ATTR_PPPOE_USER3,,,,,*req.MikrotikRateLimit,*constant,50M/50M,, diff --git a/tariffplans/pppoe/Chargers.csv b/tariffplans/pppoe/Chargers.csv new file mode 100644 index 0000000..392f5c8 --- /dev/null +++ b/tariffplans/pppoe/Chargers.csv @@ -0,0 +1,3 @@ +#Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight +cgrates.org,DEFAULT,,,*default,*none,0 +cgrates.org,Raw,,,*raw,*constant:*req.RequestType:*none,0 diff --git a/tariffplans/pppoe/DestinationRates.csv b/tariffplans/pppoe/DestinationRates.csv new file mode 100644 index 0000000..b1c5667 --- /dev/null +++ b/tariffplans/pppoe/DestinationRates.csv @@ -0,0 +1,3 @@ +#Id,DestinationId,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy +DR_DATA_TIME,DST_DATA,RT_DATA_TIME,*up,4,0, +DR_DATA_FLAT,DST_DATA,RT_DATA_FLAT,*up,4,0, diff --git a/tariffplans/pppoe/Destinations.csv b/tariffplans/pppoe/Destinations.csv new file mode 100644 index 0000000..7557b57 --- /dev/null +++ b/tariffplans/pppoe/Destinations.csv @@ -0,0 +1,2 @@ +#Id,Prefix +DST_DATA,data diff --git a/tariffplans/pppoe/Filters.csv b/tariffplans/pppoe/Filters.csv new file mode 100644 index 0000000..109c68b --- /dev/null +++ b/tariffplans/pppoe/Filters.csv @@ -0,0 +1 @@ +#Tenant,ID,Type,Path,Values,ActivationInterval diff --git a/tariffplans/pppoe/Rates.csv b/tariffplans/pppoe/Rates.csv new file mode 100644 index 0000000..018a4e3 --- /dev/null +++ b/tariffplans/pppoe/Rates.csv @@ -0,0 +1,5 @@ +#Id,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart +# Time-based rate: $0.001 per second (for prepaid session time billing) +RT_DATA_TIME,0,0.001,1s,1s,0s +# Flat rate: $0 per session (unlimited plan) +RT_DATA_FLAT,0,0,1s,1s,0s diff --git a/tariffplans/pppoe/RatingPlans.csv b/tariffplans/pppoe/RatingPlans.csv new file mode 100644 index 0000000..00ebba5 --- /dev/null +++ b/tariffplans/pppoe/RatingPlans.csv @@ -0,0 +1,3 @@ +#Id,DestinationRatesId,TimingTag,Weight +RP_DATA_TIME,DR_DATA_TIME,*any,10 +RP_DATA_FLAT,DR_DATA_FLAT,*any,10 diff --git a/tariffplans/pppoe/RatingProfiles.csv b/tariffplans/pppoe/RatingProfiles.csv new file mode 100644 index 0000000..e743db6 --- /dev/null +++ b/tariffplans/pppoe/RatingProfiles.csv @@ -0,0 +1,7 @@ +#Tenant,Category,Subject,ActivationTime,RatingPlanId,RatesFallbackSubject +# PPPoE users with time-based billing +cgrates.org,generic,pppoe_user1,2024-01-01T00:00:00Z,RP_DATA_TIME, +cgrates.org,generic,pppoe_user2,2024-01-01T00:00:00Z,RP_DATA_TIME, +cgrates.org,generic,pppoe_user3,2024-01-01T00:00:00Z,RP_DATA_TIME, +# Default fallback for any user in generic category +cgrates.org,generic,*any,2024-01-01T00:00:00Z,RP_DATA_TIME,