@@ -3,16 +3,22 @@ package lds
3
3
import (
4
4
"fmt"
5
5
"strings"
6
+ "time"
6
7
7
8
xds_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
8
9
xds_listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
10
+ xds_local_ratelimit "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/local_ratelimit/v3"
9
11
xds_tcp_proxy "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/v3"
12
+ xds_type "github.com/envoyproxy/go-control-plane/envoy/type/v3"
10
13
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
11
14
"github.com/golang/protobuf/ptypes/any"
12
15
"github.com/pkg/errors"
13
16
"google.golang.org/protobuf/types/known/anypb"
17
+ "google.golang.org/protobuf/types/known/durationpb"
14
18
"google.golang.org/protobuf/types/known/wrapperspb"
15
19
20
+ policyv1alpha1 "github.com/openservicemesh/osm/pkg/apis/policy/v1alpha1"
21
+
16
22
"github.com/openservicemesh/osm/pkg/constants"
17
23
"github.com/openservicemesh/osm/pkg/envoy"
18
24
"github.com/openservicemesh/osm/pkg/envoy/rds/route"
@@ -75,6 +81,15 @@ func (lb *listenerBuilder) getInboundHTTPFilters(trafficMatch *trafficpolicy.Tra
75
81
filters = append (filters , rbacFilter )
76
82
}
77
83
84
+ // Apply the network level local rate limit filter if configured for the TrafficMatch
85
+ if trafficMatch .RateLimit != nil && trafficMatch .RateLimit .Local != nil && trafficMatch .RateLimit .Local .TCP != nil {
86
+ rateLimitFilter , err := buildTCPLocalRateLimitFilter (trafficMatch .RateLimit .Local .TCP , trafficMatch .Name )
87
+ if err != nil {
88
+ return nil , err
89
+ }
90
+ filters = append (filters , rateLimitFilter )
91
+ }
92
+
78
93
// Build the HTTP Connection Manager filter from its options
79
94
inboundConnManager , err := httpConnManagerOptions {
80
95
direction : inbound ,
@@ -228,6 +243,15 @@ func (lb *listenerBuilder) getInboundTCPFilters(trafficMatch *trafficpolicy.Traf
228
243
filters = append (filters , rbacFilter )
229
244
}
230
245
246
+ // Apply the network level local rate limit filter if configured for the TrafficMatch
247
+ if trafficMatch .RateLimit != nil && trafficMatch .RateLimit .Local != nil && trafficMatch .RateLimit .Local .TCP != nil {
248
+ rateLimitFilter , err := buildTCPLocalRateLimitFilter (trafficMatch .RateLimit .Local .TCP , trafficMatch .Name )
249
+ if err != nil {
250
+ return nil , err
251
+ }
252
+ filters = append (filters , rateLimitFilter )
253
+ }
254
+
231
255
// Apply the TCP Proxy Filter
232
256
tcpProxy := & xds_tcp_proxy.TcpProxy {
233
257
StatPrefix : fmt .Sprintf ("%s.%s" , inboundMeshTCPProxyStatPrefix , trafficMatch .Cluster ),
@@ -248,6 +272,45 @@ func (lb *listenerBuilder) getInboundTCPFilters(trafficMatch *trafficpolicy.Traf
248
272
return filters , nil
249
273
}
250
274
275
+ func buildTCPLocalRateLimitFilter (config * policyv1alpha1.TCPLocalRateLimitSpec , statPrefix string ) (* xds_listener.Filter , error ) {
276
+ if config == nil {
277
+ return nil , nil
278
+ }
279
+
280
+ var fillInterval time.Duration
281
+ switch config .Unit {
282
+ case "second" :
283
+ fillInterval = time .Second
284
+ case "minute" :
285
+ fillInterval = time .Minute
286
+ case "hour" :
287
+ fillInterval = time .Hour
288
+ default :
289
+ return nil , errors .Errorf ("invalid unit %q for TCP connection rate limiting" , config .Unit )
290
+ }
291
+
292
+ rateLimit := & xds_local_ratelimit.LocalRateLimit {
293
+ StatPrefix : statPrefix ,
294
+ TokenBucket : & xds_type.TokenBucket {
295
+ MaxTokens : config .Connections + config .Burst ,
296
+ TokensPerFill : wrapperspb .UInt32 (config .Connections ),
297
+ FillInterval : durationpb .New (fillInterval ),
298
+ },
299
+ }
300
+
301
+ marshalledConfig , err := anypb .New (rateLimit )
302
+ if err != nil {
303
+ return nil , err
304
+ }
305
+
306
+ filter := & xds_listener.Filter {
307
+ Name : wellknown .RateLimit ,
308
+ ConfigType : & xds_listener.Filter_TypedConfig {TypedConfig : marshalledConfig },
309
+ }
310
+
311
+ return filter , nil
312
+ }
313
+
251
314
// getOutboundHTTPFilter returns an HTTP connection manager network filter used to filter outbound HTTP traffic for the given route configuration
252
315
func (lb * listenerBuilder ) getOutboundHTTPFilter (routeConfigName string ) (* xds_listener.Filter , error ) {
253
316
var marshalledFilter * any.Any
0 commit comments