Skip to content

Commit

Permalink
[agent] drop traffic to own ipns subnets on external conn
Browse files Browse the repository at this point in the history
  • Loading branch information
Frostman committed Dec 14, 2023
1 parent 1860dda commit 9ef473f
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 13 deletions.
1 change: 1 addition & 0 deletions api/agent/v1alpha2/agent_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type AgentSpec struct {
VPCPeerings map[string]vpcapi.VPCPeeringSpec `json:"vpcPeers,omitempty"`
VPCLoopbackLinks map[string]string `json:"vpcLoopbackLinks,omitempty"`
VPCLoopbackVLANs map[string]uint16 `json:"vpcLoopbackVLANs,omitempty"`
IPv4Namespaces map[string]vpcapi.IPv4NamespaceSpec `json:"ipv4Namespaces,omitempty"`
Externals map[string]vpcapi.ExternalSpec `json:"externals,omitempty"`
ExternalAttachments map[string]vpcapi.ExternalAttachmentSpec `json:"externalAttachments,omitempty"`
ExternalPeerings map[string]vpcapi.ExternalPeeringSpec `json:"externalPeerings,omitempty"`
Expand Down
7 changes: 7 additions & 0 deletions api/agent/v1alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions config/crd/bases/agent.githedgehog.com_agents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,18 @@ spec:
type: string
type: object
type: object
ipv4Namespaces:
additionalProperties:
description: IPv4NamespaceSpec defines the desired state of IPv4Namespace
properties:
subnets:
items:
type: string
maxItems: 10
minItems: 1
type: array
type: object
type: object
irbVLANs:
additionalProperties:
type: integer
Expand Down
2 changes: 2 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ _Appears in:_
| `vpcPeers` _object (keys:string, values:[VPCPeeringSpec](#vpcpeeringspec))_ | |
| `vpcLoopbackLinks` _object (keys:string, values:string)_ | |
| `vpcLoopbackVLANs` _object (keys:string, values:integer)_ | |
| `ipv4Namespaces` _object (keys:string, values:[IPv4NamespaceSpec](#ipv4namespacespec))_ | |
| `externals` _object (keys:string, values:[ExternalSpec](#externalspec))_ | |
| `externalAttachments` _object (keys:string, values:[ExternalAttachmentSpec](#externalattachmentspec))_ | |
| `externalPeerings` _object (keys:string, values:[ExternalPeeringSpec](#externalpeeringspec))_ | |
Expand Down Expand Up @@ -588,6 +589,7 @@ IPv4Namespace is the Schema for the ipv4namespaces API
IPv4NamespaceSpec defines the desired state of IPv4Namespace

_Appears in:_
- [AgentSpec](#agentspec)
- [IPv4Namespace](#ipv4namespace)

| Field | Description |
Expand Down
29 changes: 29 additions & 0 deletions pkg/agent/dozer/bcm/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,27 @@ func planExternals(agent *agentapi.Agent, spec *dozer.Spec) error {
},
}

spec.ACLs[ipnsEgressAccessList(external.IPv4Namespace)] = &dozer.SpecACL{
Entries: map[uint32]*dozer.SpecACLEntry{
65535: {
Action: dozer.SpecACLEntryActionAccept,
},
},
}

ipns, exists := agent.Spec.IPv4Namespaces[external.IPv4Namespace]
if !exists {
return errors.Errorf("ipv4 namespace %s not found for external %s", external.IPv4Namespace, externalName)
}
seq := uint32(10)
for _, subnet := range ipns.Subnets {
spec.ACLs[ipnsEgressAccessList(external.IPv4Namespace)].Entries[seq] = &dozer.SpecACLEntry{
DestinationAddress: stringPtr(subnet),
Action: dozer.SpecACLEntryActionDrop,
}
seq += 10
}

if spec.VRFs[ipnsVrfName] == nil {
protocolIP, _, err := net.ParseCIDR(agent.Spec.Switch.ProtocolIP)
if err != nil {
Expand Down Expand Up @@ -637,6 +658,10 @@ func planExternals(agent *agentapi.Agent, spec *dozer.Spec) error {
IPv4UnicastImportPolicies: []string{inboundRouteMapName(attach.External)},
IPv4UnicastExportPolicies: []string{outboundRouteMapName(attach.External)},
}

spec.ACLInterfaces[subIfaceName] = &dozer.SpecACLInterface{
Egress: stringPtr(ipnsEgressAccessList(ipns)),
}
}

return nil
Expand Down Expand Up @@ -1453,6 +1478,10 @@ func importVrfRouteMapName(vpc string) string {
return fmt.Sprintf("import-vrf--%s", vpc)
}

func ipnsEgressAccessList(ipns string) string {
return fmt.Sprintf("ipns-egress--%s", ipns)
}

func stringPtr(s string) *string { return &s }

func uint8Ptr(u uint8) *uint8 { return &u }
Expand Down
57 changes: 44 additions & 13 deletions pkg/agent/dozer/bcm/spec_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,20 +147,40 @@ var specACLInterfaceEnforcer = &DefaultValueEnforcer[string, *dozer.SpecACLInter
UpdateWeight: ActionWeightACLInterfaceUpdate,
DeleteWeight: ActionWeightACLInterfaceDelete,
Marshal: func(name string, value *dozer.SpecACLInterface) (ygot.ValidatedGoStruct, error) {
aclSets := &oc.OpenconfigAcl_Acl_Interfaces_Interface_IngressAclSets{
IngressAclSet: map[oc.OpenconfigAcl_Acl_Interfaces_Interface_IngressAclSets_IngressAclSet_Key]*oc.OpenconfigAcl_Acl_Interfaces_Interface_IngressAclSets_IngressAclSet{},
var ingressAclSets *oc.OpenconfigAcl_Acl_Interfaces_Interface_IngressAclSets
if value.Ingress != nil {
ingressAclSets = &oc.OpenconfigAcl_Acl_Interfaces_Interface_IngressAclSets{
IngressAclSet: map[oc.OpenconfigAcl_Acl_Interfaces_Interface_IngressAclSets_IngressAclSet_Key]*oc.OpenconfigAcl_Acl_Interfaces_Interface_IngressAclSets_IngressAclSet{
{
SetName: *value.Ingress,
Type: oc.OpenconfigAcl_ACL_TYPE_ACL_IPV4,
}: {
SetName: value.Ingress,
Type: oc.OpenconfigAcl_ACL_TYPE_ACL_IPV4,
Config: &oc.OpenconfigAcl_Acl_Interfaces_Interface_IngressAclSets_IngressAclSet_Config{
SetName: value.Ingress,
Type: oc.OpenconfigAcl_ACL_TYPE_ACL_IPV4,
},
},
},
}
}

if value.Ingress != nil {
aclSets.IngressAclSet[oc.OpenconfigAcl_Acl_Interfaces_Interface_IngressAclSets_IngressAclSet_Key{
SetName: *value.Ingress,
Type: oc.OpenconfigAcl_ACL_TYPE_ACL_IPV4,
}] = &oc.OpenconfigAcl_Acl_Interfaces_Interface_IngressAclSets_IngressAclSet{
SetName: value.Ingress,
Type: oc.OpenconfigAcl_ACL_TYPE_ACL_IPV4,
Config: &oc.OpenconfigAcl_Acl_Interfaces_Interface_IngressAclSets_IngressAclSet_Config{
SetName: value.Ingress,
Type: oc.OpenconfigAcl_ACL_TYPE_ACL_IPV4,
var egressAclSets *oc.OpenconfigAcl_Acl_Interfaces_Interface_EgressAclSets
if value.Egress != nil {
egressAclSets = &oc.OpenconfigAcl_Acl_Interfaces_Interface_EgressAclSets{
EgressAclSet: map[oc.OpenconfigAcl_Acl_Interfaces_Interface_EgressAclSets_EgressAclSet_Key]*oc.OpenconfigAcl_Acl_Interfaces_Interface_EgressAclSets_EgressAclSet{
{
SetName: *value.Egress,
Type: oc.OpenconfigAcl_ACL_TYPE_ACL_IPV4,
}: {
SetName: value.Egress,
Type: oc.OpenconfigAcl_ACL_TYPE_ACL_IPV4,
Config: &oc.OpenconfigAcl_Acl_Interfaces_Interface_EgressAclSets_EgressAclSet_Config{
SetName: value.Egress,
Type: oc.OpenconfigAcl_ACL_TYPE_ACL_IPV4,
},
},
},
}
}
Expand All @@ -177,7 +197,8 @@ var specACLInterfaceEnforcer = &DefaultValueEnforcer[string, *dozer.SpecACLInter
Interface: ygot.String(name),
},
},
IngressAclSets: aclSets,
IngressAclSets: ingressAclSets,
EgressAclSets: egressAclSets,
},
},
}, nil
Expand Down Expand Up @@ -302,6 +323,7 @@ func unmarshalOCACLInterfaces(ocVal *oc.OpenconfigAcl_Acl) (map[string]*dozer.Sp
}

var ingress *string
var egress *string

for key, value := range iface.IngressAclSets.IngressAclSet {
if key.Type != oc.OpenconfigAcl_ACL_TYPE_ACL_IPV4 {
Expand All @@ -311,8 +333,17 @@ func unmarshalOCACLInterfaces(ocVal *oc.OpenconfigAcl_Acl) (map[string]*dozer.Sp
ingress = value.SetName
}

for key, value := range iface.EgressAclSets.EgressAclSet {
if key.Type != oc.OpenconfigAcl_ACL_TYPE_ACL_IPV4 {
continue
}

egress = value.SetName
}

interfaces[name] = &dozer.SpecACLInterface{
Ingress: ingress,
Egress: egress,
}
}

Expand Down
1 change: 1 addition & 0 deletions pkg/agent/dozer/dozer.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ const (

type SpecACLInterface struct {
Ingress *string `json:"ingress,omitempty"`
Egress *string `json:"egress,omitempty"`
}

type SpecVXLANTunnel struct {
Expand Down
12 changes: 12 additions & 0 deletions pkg/ctrl/agent/agent_ctrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,17 @@ func (r *AgentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl
}
}

ipv4NamespaceList := &vpcapi.IPv4NamespaceList{}
err = r.List(ctx, ipv4NamespaceList, client.InNamespace(sw.Namespace))
if err != nil {
return ctrl.Result{}, errors.Wrapf(err, "error listing ipv4 namespaces")
}

ipv4Namespaces := map[string]vpcapi.IPv4NamespaceSpec{}
for _, ns := range ipv4NamespaceList.Items {
ipv4Namespaces[ns.Name] = ns.Spec
}

agent := &agentapi.Agent{ObjectMeta: switchNsName}
_, err = ctrlutil.CreateOrUpdate(ctx, r.Client, agent, func() error {
agent.Labels = sw.Labels
Expand All @@ -424,6 +435,7 @@ func (r *AgentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl
agent.Spec.VPCs = vpcs
agent.Spec.VPCAttachments = attaches
agent.Spec.VPCPeerings = peers
agent.Spec.IPv4Namespaces = ipv4Namespaces
agent.Spec.Externals = externals
agent.Spec.ExternalAttachments = externalAttaches
agent.Spec.ExternalPeerings = externalPeerings
Expand Down

0 comments on commit 9ef473f

Please sign in to comment.