mirror of
https://github.com/agent-substrate/substrate.git
synced 2026-10-02 03:24:42 +08:00
ateapi: rename IPBlockRule to CIDRRule (#1597)
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -202,7 +202,7 @@ func ValidateCustom_EgressRuleEffects_InjectStaticHeaders(_ context.Context, _ o
|
||||
return errs
|
||||
}
|
||||
|
||||
func ValidateCustom_IPBlockRule_Cidrs(_ context.Context, _ operation.Operation, p *field.Path, cidrs, _ []string) field.ErrorList {
|
||||
func ValidateCustom_CIDRRule_Cidrs(_ context.Context, _ operation.Operation, p *field.Path, cidrs, _ []string) field.ErrorList {
|
||||
var errs field.ErrorList
|
||||
for i, cidr := range cidrs {
|
||||
errs = append(errs, validation.IsValidCIDR(p.Index(i), cidr)...)
|
||||
|
||||
@@ -569,18 +569,18 @@ func TestValidateEgressPolicyRules(t *testing.T) {
|
||||
}, {
|
||||
name: "canonical IPv4 CIDR",
|
||||
mutate: func(p *ateapipb.EgressPolicy) {
|
||||
p.Rules[0] = &ateapipb.EgressRule{IpBlocks: &ateapipb.IPBlockRule{Cidrs: []string{"192.0.2.0/24"}}}
|
||||
p.Rules[0] = &ateapipb.EgressRule{Cidrs: &ateapipb.CIDRRule{Cidrs: []string{"192.0.2.0/24"}}}
|
||||
},
|
||||
}, {
|
||||
name: "canonical IPv6 CIDR",
|
||||
mutate: func(p *ateapipb.EgressPolicy) {
|
||||
p.Rules[0] = &ateapipb.EgressRule{IpBlocks: &ateapipb.IPBlockRule{Cidrs: []string{"2001:db8::/32"}}}
|
||||
p.Rules[0] = &ateapipb.EgressRule{Cidrs: &ateapipb.CIDRRule{Cidrs: []string{"2001:db8::/32"}}}
|
||||
},
|
||||
}, {
|
||||
name: "mixed IPv4 and IPv6 CIDRs",
|
||||
mutate: func(p *ateapipb.EgressPolicy) {
|
||||
p.Rules[0] = &ateapipb.EgressRule{
|
||||
IpBlocks: &ateapipb.IPBlockRule{
|
||||
Cidrs: &ateapipb.CIDRRule{
|
||||
Cidrs: []string{"192.0.2.0/24", "2001:db8::/32"},
|
||||
},
|
||||
}
|
||||
@@ -593,7 +593,7 @@ func TestValidateEgressPolicyRules(t *testing.T) {
|
||||
cidrs = append(cidrs, fmt.Sprintf("192.0.2.%d/32", i))
|
||||
}
|
||||
p.Rules[0] = &ateapipb.EgressRule{
|
||||
IpBlocks: &ateapipb.IPBlockRule{
|
||||
Cidrs: &ateapipb.CIDRRule{
|
||||
Cidrs: cidrs,
|
||||
},
|
||||
}
|
||||
@@ -606,45 +606,45 @@ func TestValidateEgressPolicyRules(t *testing.T) {
|
||||
cidrs = append(cidrs, fmt.Sprintf("192.0.2.%d/32", i))
|
||||
}
|
||||
p.Rules[0] = &ateapipb.EgressRule{
|
||||
IpBlocks: &ateapipb.IPBlockRule{
|
||||
Cidrs: &ateapipb.CIDRRule{
|
||||
Cidrs: cidrs,
|
||||
},
|
||||
}
|
||||
},
|
||||
want: field.ErrorList{
|
||||
field.TooMany(rule.Child("ip_blocks", "cidrs"), 257, 256).WithOrigin("maxItems"),
|
||||
field.TooMany(rule.Child("cidrs", "cidrs"), 257, 256).WithOrigin("maxItems"),
|
||||
},
|
||||
}, {
|
||||
name: "missing CIDR",
|
||||
mutate: func(p *ateapipb.EgressPolicy) {
|
||||
p.Rules[0] = &ateapipb.EgressRule{IpBlocks: &ateapipb.IPBlockRule{Cidrs: []string{""}}}
|
||||
p.Rules[0] = &ateapipb.EgressRule{Cidrs: &ateapipb.CIDRRule{Cidrs: []string{""}}}
|
||||
},
|
||||
want: field.ErrorList{
|
||||
field.Invalid(rule.Child("ip_blocks", "cidrs").Index(0), "", "must be a canonical IPv4 or IPv6 prefix"),
|
||||
field.Invalid(rule.Child("cidrs", "cidrs").Index(0), "", "must be a canonical IPv4 or IPv6 prefix"),
|
||||
},
|
||||
}, {
|
||||
name: "empty CIDR list",
|
||||
mutate: func(p *ateapipb.EgressPolicy) {
|
||||
p.Rules[0] = &ateapipb.EgressRule{IpBlocks: &ateapipb.IPBlockRule{}}
|
||||
p.Rules[0] = &ateapipb.EgressRule{Cidrs: &ateapipb.CIDRRule{}}
|
||||
},
|
||||
want: field.ErrorList{
|
||||
field.Required(rule.Child("ip_blocks", "cidrs"), ""),
|
||||
field.Required(rule.Child("cidrs", "cidrs"), ""),
|
||||
},
|
||||
}, {
|
||||
name: "noncanonical CIDR",
|
||||
mutate: func(p *ateapipb.EgressPolicy) {
|
||||
p.Rules[0] = &ateapipb.EgressRule{IpBlocks: &ateapipb.IPBlockRule{Cidrs: []string{"192.0.2.1/24"}}}
|
||||
p.Rules[0] = &ateapipb.EgressRule{Cidrs: &ateapipb.CIDRRule{Cidrs: []string{"192.0.2.1/24"}}}
|
||||
},
|
||||
want: field.ErrorList{
|
||||
field.Invalid(rule.Child("ip_blocks", "cidrs").Index(0), "192.0.2.1/24", "must be a canonical IPv4 or IPv6 prefix"),
|
||||
field.Invalid(rule.Child("cidrs", "cidrs").Index(0), "192.0.2.1/24", "must be a canonical IPv4 or IPv6 prefix"),
|
||||
},
|
||||
}, {
|
||||
name: "duplicate CIDR",
|
||||
mutate: func(p *ateapipb.EgressPolicy) {
|
||||
p.Rules[0] = &ateapipb.EgressRule{IpBlocks: &ateapipb.IPBlockRule{Cidrs: []string{"192.0.2.0/24", "192.0.2.0/24"}}}
|
||||
p.Rules[0] = &ateapipb.EgressRule{Cidrs: &ateapipb.CIDRRule{Cidrs: []string{"192.0.2.0/24", "192.0.2.0/24"}}}
|
||||
},
|
||||
want: field.ErrorList{
|
||||
field.Duplicate(rule.Child("ip_blocks", "cidrs").Index(1), "192.0.2.0/24"),
|
||||
field.Duplicate(rule.Child("cidrs", "cidrs").Index(1), "192.0.2.0/24"),
|
||||
},
|
||||
}, {
|
||||
name: "missing static header",
|
||||
|
||||
@@ -1067,6 +1067,56 @@ func Validate_Atespace(
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_CIDRRule validates an instance of CIDRRule according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_CIDRRule(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *ateapipb.CIDRRule) (errs field.ErrorList) {
|
||||
|
||||
{ // field ateapipb.CIDRRule.Cidrs
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj []string,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if ateDeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.MaxItems(ctx, op, fldPath, obj, oldObj, 256).MarkShortCircuit(); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
earlyReturn = true
|
||||
}
|
||||
if e := validate.RequiredSlice(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// custom validation
|
||||
if e := ValidateCustom_CIDRRule_Cidrs(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
// lists with set semantics require unique values
|
||||
if e := validate.ValSliceUnique(ctx, op, fldPath, obj, oldObj, validate.DirectEqual); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *ateapipb.CIDRRule) []string {
|
||||
return oldObj.Cidrs
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("cidrs"), obj.Cidrs, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_Capabilities validates an instance of Capabilities according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Capabilities(
|
||||
@@ -2605,7 +2655,7 @@ func Validate_EgressPolicy(
|
||||
return errs
|
||||
}
|
||||
|
||||
var unionMembershipFor_github_com_agent_substrate_substrate_pkg_proto_ateapipb_EgressRule_ = validate.NewUnionMembership(validate.NewUnionMember("hostnames"), validate.NewUnionMember("ip_blocks"), validate.NewUnionMember("all"))
|
||||
var unionMembershipFor_github_com_agent_substrate_substrate_pkg_proto_ateapipb_EgressRule_ = validate.NewUnionMembership(validate.NewUnionMember("hostnames"), validate.NewUnionMember("cidrs"), validate.NewUnionMember("all"))
|
||||
|
||||
// Validate_EgressRule validates an instance of EgressRule according
|
||||
// to declarative validation rules in the API schema.
|
||||
@@ -2624,7 +2674,7 @@ func Validate_EgressRule(
|
||||
if obj == nil {
|
||||
return false
|
||||
}
|
||||
return obj.IpBlocks != nil
|
||||
return obj.Cidrs != nil
|
||||
},
|
||||
func(obj *ateapipb.EgressRule) bool {
|
||||
if obj == nil {
|
||||
@@ -2665,10 +2715,10 @@ func Validate_EgressRule(
|
||||
errs = append(errs, fn(fldPath.Child("hostnames"), obj.Hostnames, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
{ // field ateapipb.EgressRule.IpBlocks
|
||||
{ // field ateapipb.EgressRule.Cidrs
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *ateapipb.IPBlockRule,
|
||||
obj, oldObj *ateapipb.CIDRRule,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
@@ -2685,14 +2735,14 @@ func Validate_EgressRule(
|
||||
return // do not proceed
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_IPBlockRule(ctx, op, fldPath, obj, oldObj)...)
|
||||
errs = append(errs, Validate_CIDRRule(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *ateapipb.EgressRule) *ateapipb.IPBlockRule {
|
||||
return oldObj.IpBlocks
|
||||
func(oldObj *ateapipb.EgressRule) *ateapipb.CIDRRule {
|
||||
return oldObj.Cidrs
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("ip_blocks"), obj.IpBlocks, oldVal, oldObj != nil)...)
|
||||
errs = append(errs, fn(fldPath.Child("cidrs"), obj.Cidrs, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
{ // field ateapipb.EgressRule.All
|
||||
@@ -3753,56 +3803,6 @@ func Validate_HostnameRule(
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_IPBlockRule validates an instance of IPBlockRule according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_IPBlockRule(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *ateapipb.IPBlockRule) (errs field.ErrorList) {
|
||||
|
||||
{ // field ateapipb.IPBlockRule.Cidrs
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj []string,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if ateDeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.MaxItems(ctx, op, fldPath, obj, oldObj, 256).MarkShortCircuit(); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
earlyReturn = true
|
||||
}
|
||||
if e := validate.RequiredSlice(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// custom validation
|
||||
if e := ValidateCustom_IPBlockRule_Cidrs(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
// lists with set semantics require unique values
|
||||
if e := validate.ValSliceUnique(ctx, op, fldPath, obj, oldObj, validate.DirectEqual); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *ateapipb.IPBlockRule) []string {
|
||||
return oldObj.Cidrs
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("cidrs"), obj.Cidrs, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_ImageVolumeSource validates an instance of ImageVolumeSource according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_ImageVolumeSource(
|
||||
|
||||
@@ -1148,11 +1148,11 @@ type EgressRule struct {
|
||||
// +k8s:optional
|
||||
// +k8s:unionMember
|
||||
Hostnames *HostnameRule `protobuf:"bytes,1,opt,name=hostnames,proto3" json:"hostnames,omitempty"`
|
||||
// Matches when the original destination IP belongs to any configured block.
|
||||
// Matches when the original destination IP belongs to any configured prefix.
|
||||
//
|
||||
// +k8s:optional
|
||||
// +k8s:unionMember
|
||||
IpBlocks *IPBlockRule `protobuf:"bytes,2,opt,name=ip_blocks,json=ipBlocks,proto3" json:"ip_blocks,omitempty"`
|
||||
Cidrs *CIDRRule `protobuf:"bytes,2,opt,name=cidrs,proto3" json:"cidrs,omitempty"`
|
||||
// Matches every destination.
|
||||
//
|
||||
// +k8s:optional
|
||||
@@ -1199,9 +1199,9 @@ func (x *EgressRule) GetHostnames() *HostnameRule {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *EgressRule) GetIpBlocks() *IPBlockRule {
|
||||
func (x *EgressRule) GetCidrs() *CIDRRule {
|
||||
if x != nil {
|
||||
return x.IpBlocks
|
||||
return x.Cidrs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1291,8 +1291,8 @@ func (x *HostnameRule) GetEffects() *EgressRuleEffects {
|
||||
return nil
|
||||
}
|
||||
|
||||
// IPBlockRule matches requests by original destination IP address.
|
||||
type IPBlockRule struct {
|
||||
// CIDRRule matches requests by original destination IP address.
|
||||
type CIDRRule struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Canonical IPv4 or IPv6 CIDR prefixes. IPv4 uses dotted-decimal notation,
|
||||
// such as "192.0.2.0/24". IPv6 uses lowercase compressed notation, such as
|
||||
@@ -1308,20 +1308,20 @@ type IPBlockRule struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *IPBlockRule) Reset() {
|
||||
*x = IPBlockRule{}
|
||||
func (x *CIDRRule) Reset() {
|
||||
*x = CIDRRule{}
|
||||
mi := &file_ateapi_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *IPBlockRule) String() string {
|
||||
func (x *CIDRRule) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*IPBlockRule) ProtoMessage() {}
|
||||
func (*CIDRRule) ProtoMessage() {}
|
||||
|
||||
func (x *IPBlockRule) ProtoReflect() protoreflect.Message {
|
||||
func (x *CIDRRule) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ateapi_proto_msgTypes[9]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@@ -1333,12 +1333,12 @@ func (x *IPBlockRule) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use IPBlockRule.ProtoReflect.Descriptor instead.
|
||||
func (*IPBlockRule) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use CIDRRule.ProtoReflect.Descriptor instead.
|
||||
func (*CIDRRule) Descriptor() ([]byte, []int) {
|
||||
return file_ateapi_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *IPBlockRule) GetCidrs() []string {
|
||||
func (x *CIDRRule) GetCidrs() []string {
|
||||
if x != nil {
|
||||
return x.Cidrs
|
||||
}
|
||||
@@ -6905,16 +6905,16 @@ const file_ateapi_proto_rawDesc = "" +
|
||||
"\x06status\x18\a \x01(\v2\x13.ateapi.ActorStatusR\x06status\"n\n" +
|
||||
"\fEgressPolicy\x124\n" +
|
||||
"\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\x12(\n" +
|
||||
"\x05rules\x18\x02 \x03(\v2\x12.ateapi.EgressRuleR\x05rules\"\x9c\x01\n" +
|
||||
"\x05rules\x18\x02 \x03(\v2\x12.ateapi.EgressRuleR\x05rules\"\x92\x01\n" +
|
||||
"\n" +
|
||||
"EgressRule\x122\n" +
|
||||
"\thostnames\x18\x01 \x01(\v2\x14.ateapi.HostnameRuleR\thostnames\x120\n" +
|
||||
"\tip_blocks\x18\x02 \x01(\v2\x13.ateapi.IPBlockRuleR\bipBlocks\x12(\n" +
|
||||
"\thostnames\x18\x01 \x01(\v2\x14.ateapi.HostnameRuleR\thostnames\x12&\n" +
|
||||
"\x05cidrs\x18\x02 \x01(\v2\x10.ateapi.CIDRRuleR\x05cidrs\x12(\n" +
|
||||
"\x03all\x18\x03 \x01(\v2\x16.google.protobuf.EmptyR\x03all\"_\n" +
|
||||
"\fHostnameRule\x12\x1a\n" +
|
||||
"\bpatterns\x18\x01 \x03(\tR\bpatterns\x123\n" +
|
||||
"\aeffects\x18\x02 \x01(\v2\x19.ateapi.EgressRuleEffectsR\aeffects\"#\n" +
|
||||
"\vIPBlockRule\x12\x14\n" +
|
||||
"\aeffects\x18\x02 \x01(\v2\x19.ateapi.EgressRuleEffectsR\aeffects\" \n" +
|
||||
"\bCIDRRule\x12\x14\n" +
|
||||
"\x05cidrs\x18\x01 \x03(\tR\x05cidrs\"j\n" +
|
||||
"\x11EgressRuleEffects\x12U\n" +
|
||||
"\x15inject_static_headers\x18\x01 \x03(\v2!.ateapi.CredentialHeaderInjectionR\x13injectStaticHeaders\"r\n" +
|
||||
@@ -7319,7 +7319,7 @@ var file_ateapi_proto_goTypes = []any{
|
||||
(*EgressPolicy)(nil), // 15: ateapi.EgressPolicy
|
||||
(*EgressRule)(nil), // 16: ateapi.EgressRule
|
||||
(*HostnameRule)(nil), // 17: ateapi.HostnameRule
|
||||
(*IPBlockRule)(nil), // 18: ateapi.IPBlockRule
|
||||
(*CIDRRule)(nil), // 18: ateapi.CIDRRule
|
||||
(*EgressRuleEffects)(nil), // 19: ateapi.EgressRuleEffects
|
||||
(*CredentialHeaderInjection)(nil), // 20: ateapi.CredentialHeaderInjection
|
||||
(*ActorStatus)(nil), // 21: ateapi.ActorStatus
|
||||
@@ -7428,7 +7428,7 @@ var file_ateapi_proto_depIdxs = []int32{
|
||||
12, // 12: ateapi.EgressPolicy.metadata:type_name -> ateapi.ResourceMetadata
|
||||
16, // 13: ateapi.EgressPolicy.rules:type_name -> ateapi.EgressRule
|
||||
17, // 14: ateapi.EgressRule.hostnames:type_name -> ateapi.HostnameRule
|
||||
18, // 15: ateapi.EgressRule.ip_blocks:type_name -> ateapi.IPBlockRule
|
||||
18, // 15: ateapi.EgressRule.cidrs:type_name -> ateapi.CIDRRule
|
||||
109, // 16: ateapi.EgressRule.all:type_name -> google.protobuf.Empty
|
||||
19, // 17: ateapi.HostnameRule.effects:type_name -> ateapi.EgressRuleEffects
|
||||
20, // 18: ateapi.EgressRuleEffects.inject_static_headers:type_name -> ateapi.CredentialHeaderInjection
|
||||
|
||||
@@ -415,11 +415,11 @@ message EgressRule {
|
||||
// +k8s:unionMember
|
||||
HostnameRule hostnames = 1;
|
||||
|
||||
// Matches when the original destination IP belongs to any configured block.
|
||||
// Matches when the original destination IP belongs to any configured prefix.
|
||||
//
|
||||
// +k8s:optional
|
||||
// +k8s:unionMember
|
||||
IPBlockRule ip_blocks = 2;
|
||||
CIDRRule cidrs = 2;
|
||||
|
||||
// Matches every destination.
|
||||
//
|
||||
@@ -460,8 +460,8 @@ message HostnameRule {
|
||||
EgressRuleEffects effects = 2;
|
||||
}
|
||||
|
||||
// IPBlockRule matches requests by original destination IP address.
|
||||
message IPBlockRule {
|
||||
// CIDRRule matches requests by original destination IP address.
|
||||
message CIDRRule {
|
||||
// Canonical IPv4 or IPv6 CIDR prefixes. IPv4 uses dotted-decimal notation,
|
||||
// such as "192.0.2.0/24". IPv6 uses lowercase compressed notation, such as
|
||||
// "2001:db8::/32". Bits after the prefix length must be zero. The rule
|
||||
|
||||
Reference in New Issue
Block a user