Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 28 additions & 22 deletions calico-vpp-agent/felix/felix_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
"github.com/projectcalico/vpp-dataplane/v3/calico-vpp-agent/watchers"
"github.com/projectcalico/vpp-dataplane/v3/config"
"github.com/projectcalico/vpp-dataplane/v3/vpplink"
"github.com/projectcalico/vpp-dataplane/v3/vpplink/generated/bindings/npol"
"github.com/projectcalico/vpp-dataplane/v3/vpplink/types"
)

Expand Down Expand Up @@ -82,6 +83,7 @@ type Server struct {
/* workloadToHost may drop traffic that goes from the pods to the host */
workloadsToHostPolicy *Policy
defaultTap0IngressConf []uint32
defaultTap0EgressConf []uint32
/* always allow traffic coming from host to the pods (for healthchecks and so on) */
// AllowFromHostPolicy persists the policy allowing host --> pod communications.
// See CreateAllowFromHostPolicy definition
Expand All @@ -90,9 +92,10 @@ type Server struct {
allPodsIpset *IPSet
/* allow traffic between uplink/tunnels and tap interfaces */
allowToHostPolicy *Policy
ip4 *net.IP
ip6 *net.IP
interfacesMap map[string]interfaceDetails
/* deny all policy for heps with no policies defined */
ip4 *net.IP
ip6 *net.IP
interfacesMap map[string]interfaceDetails

felixServerEventChan chan common.CalicoVppEvent
networkDefinitions map[string]*watchers.NetworkDefinition
Expand Down Expand Up @@ -953,6 +956,22 @@ func (s *Server) handleHostEndpointUpdate(msg *proto.HostEndpointUpdate, pending
// we are not supposed to fallback to expectedIPs if interfaceName doesn't match
// this is the current behavior in calico linux
s.log.Errorf("cannot find host endpoint: interface named %s does not exist", hep.InterfaceName)
// *************************** this is temporary, for dev
if hep.expectedIPs != nil {
for _, existingIf := range s.interfacesMap {
interfaceFound1:
for _, address := range existingIf.addresses {
for _, expectedIP := range hep.expectedIPs {
if address == expectedIP {
hep.UplinkSwIfIndexes = append(hep.UplinkSwIfIndexes, existingIf.uplinkIndex)
hep.TapSwIfIndexes = append(hep.TapSwIfIndexes, existingIf.tapIndex)
break interfaceFound1
}
}
}
}
}
// ***************************
}
} else if hep.InterfaceName == "" && hep.expectedIPs != nil {
for _, existingIf := range s.interfacesMap {
Expand Down Expand Up @@ -1696,24 +1715,10 @@ func (s *Server) createEndpointToHostPolicy( /*may be return*/ ) (err error) {
}
s.workloadsToHostPolicy = workloadsToHostPolicy

allowAllPol := &Policy{
Policy: &types.Policy{},
VppID: types.InvalidID,
InboundRules: []*Rule{
{
VppID: types.InvalidID,
Rule: &types.Rule{
Action: types.ActionAllow,
},
},
},
}
err = allowAllPol.Create(s.vpp, &ps)
if err != nil {
return err
}
conf := types.NewInterfaceConfig()
conf.IngressPolicyIDs = append(conf.IngressPolicyIDs, s.workloadsToHostPolicy.VppID, allowAllPol.VppID)
conf.IngressPolicyIDs = append(conf.IngressPolicyIDs, s.workloadsToHostPolicy.VppID)
conf.PolicyDefaultTx = npol.NPOL_DEFAULT_ALLOW
conf.PolicyDefaultRx = npol.NPOL_DEFAULT_ALLOW
swifindexes, err := s.vpp.SearchInterfacesWithTagPrefix("host-") // tap0 interfaces
if err != nil {
s.log.Error(err)
Expand All @@ -1725,6 +1730,7 @@ func (s *Server) createEndpointToHostPolicy( /*may be return*/ ) (err error) {
}
}
s.defaultTap0IngressConf = conf.IngressPolicyIDs
s.defaultTap0EgressConf = conf.EgressPolicyIDs
return nil
}

Expand Down Expand Up @@ -1753,7 +1759,7 @@ func (s *Server) createFailSafePolicies() (err error) {
DstPortRange: []types.PortRange{{First: protoPort.Port, Last: protoPort.Port}},
Filters: []types.RuleFilter{{
ShouldMatch: true,
Type: types.CapoFilterProto,
Type: types.NpolFilterProto,
Value: int(protocol),
}},
},
Expand Down Expand Up @@ -1787,7 +1793,7 @@ func (s *Server) createFailSafePolicies() (err error) {
DstPortRange: []types.PortRange{{First: protoPort.Port, Last: protoPort.Port}},
Filters: []types.RuleFilter{{
ShouldMatch: true,
Type: types.CapoFilterProto,
Type: types.NpolFilterProto,
Value: int(protocol),
}},
},
Expand Down
54 changes: 47 additions & 7 deletions calico-vpp-agent/felix/host_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/projectcalico/calico/felix/proto"

"github.com/projectcalico/vpp-dataplane/v3/vpplink"
"github.com/projectcalico/vpp-dataplane/v3/vpplink/generated/bindings/npol"
"github.com/projectcalico/vpp-dataplane/v3/vpplink/types"
)

Expand Down Expand Up @@ -134,7 +135,7 @@ func (h *HostEndpoint) handleTunnelChange(swIfIndex uint32, isAdd bool, pending
return err
}

func (h *HostEndpoint) getHostPolicies(state *PolicyState, tiers []Tier) (conf *types.InterfaceConfig, err error) {
func (h *HostEndpoint) getUserDefinedPolicies(state *PolicyState, tiers []Tier) (conf *types.InterfaceConfig, err error) {
conf = types.NewInterfaceConfig()
for _, tier := range tiers {
for _, polName := range tier.IngressPolicies {
Expand Down Expand Up @@ -171,32 +172,70 @@ func (h *HostEndpoint) getHostPolicies(state *PolicyState, tiers []Tier) (conf *
return conf, nil
}

/*
This function creates the interface configuration for the host, applied on the vpptap0
interface i.e. the tap interface from VPP to the host
that we use as controlpoint for HostEndpoint implementation
We have an implicit workloadsToHostPolicy policy that controls the traffic from
workloads to their host: it is defined by felixConfig.DefaultEndpointToHostAction
We have an implicit failsafe rules policy defined by felixConfig as well.

If there are no policies the default should be pass to profiles
If there are policies the default should be deny (profiles are ignored)
*/
func (h *HostEndpoint) getTapPolicies(state *PolicyState) (conf *types.InterfaceConfig, err error) {
conf, err = h.getHostPolicies(state, h.Tiers)
conf, err = h.getUserDefinedPolicies(state, h.Tiers)
if err != nil {
return nil, errors.Wrap(err, "cannot create host policies for TapConf")
}
if len(conf.IngressPolicyIDs) > 0 {
conf.IngressPolicyIDs = append(conf.IngressPolicyIDs, h.server.workloadsToHostPolicy.VppID)
if len(conf.IngressPolicyIDs) == 0 && len(conf.ProfileIDs) == 0 {
// If a host endpoint is created and network policy is not in place,
// the Calico default is to deny traffic to/from that endpoint
// (except for traffic allowed by failsafe rules).
// note: this applies to ingress and egress separately, so if you don't have
// ingress only you drop ingress
conf.IngressPolicyIDs = []uint32{h.server.workloadsToHostPolicy.VppID, h.server.failSafePolicy.VppID}
conf.PolicyDefaultTx = npol.NPOL_DEFAULT_DENY
} else {
if len(conf.IngressPolicyIDs) > 0 {
conf.PolicyDefaultTx = npol.NPOL_DEFAULT_DENY
} else if len(conf.ProfileIDs) > 0 {
conf.PolicyDefaultTx = npol.NPOL_DEFAULT_PASS
}
conf.IngressPolicyIDs = append([]uint32{h.server.failSafePolicy.VppID}, conf.IngressPolicyIDs...)
conf.IngressPolicyIDs = append([]uint32{h.server.workloadsToHostPolicy.VppID}, conf.IngressPolicyIDs...)
}
if len(conf.EgressPolicyIDs) > 0 {
conf.EgressPolicyIDs = append([]uint32{h.server.AllowFromHostPolicy.VppID}, conf.EgressPolicyIDs...)
if len(conf.EgressPolicyIDs) == 0 && len(conf.ProfileIDs) == 0 {
conf.EgressPolicyIDs = []uint32{h.server.AllowFromHostPolicy.VppID, h.server.failSafePolicy.VppID}
conf.PolicyDefaultRx = npol.NPOL_DEFAULT_DENY
} else {
if len(conf.EgressPolicyIDs) > 0 {
conf.PolicyDefaultRx = npol.NPOL_DEFAULT_DENY
} else if len(conf.ProfileIDs) > 0 {
conf.PolicyDefaultRx = npol.NPOL_DEFAULT_PASS
}
conf.EgressPolicyIDs = append([]uint32{h.server.failSafePolicy.VppID}, conf.EgressPolicyIDs...)
conf.EgressPolicyIDs = append([]uint32{h.server.AllowFromHostPolicy.VppID}, conf.EgressPolicyIDs...)
}
return conf, nil
}

func (h *HostEndpoint) getForwardPolicies(state *PolicyState) (conf *types.InterfaceConfig, err error) {
conf, err = h.getHostPolicies(state, h.ForwardTiers)
conf, err = h.getUserDefinedPolicies(state, h.ForwardTiers)
if err != nil {
return nil, errors.Wrap(err, "cannot create host policies for forwardConf")
}
if len(conf.EgressPolicyIDs) > 0 {
conf.EgressPolicyIDs = append([]uint32{h.server.allowToHostPolicy.VppID}, conf.EgressPolicyIDs...)
conf.PolicyDefaultRx = npol.NPOL_DEFAULT_DENY
} else if len(conf.ProfileIDs) > 0 {
conf.PolicyDefaultRx = npol.NPOL_DEFAULT_PASS
}
if len(conf.IngressPolicyIDs) > 0 {
conf.IngressPolicyIDs = append([]uint32{h.server.allowToHostPolicy.VppID}, conf.IngressPolicyIDs...)
conf.PolicyDefaultTx = npol.NPOL_DEFAULT_DENY
} else if len(conf.ProfileIDs) > 0 {
conf.PolicyDefaultTx = npol.NPOL_DEFAULT_PASS
}
return conf, nil
}
Expand Down Expand Up @@ -273,6 +312,7 @@ func (h *HostEndpoint) Delete(vpp *vpplink.VppLink, state *PolicyState) (err err
h.server.log.Infof("policy(del) interface swif=%d", swIfIndex)
conf := types.NewInterfaceConfig()
conf.IngressPolicyIDs = h.server.defaultTap0IngressConf
conf.EgressPolicyIDs = h.server.defaultTap0EgressConf
err = vpp.ConfigurePolicies(swIfIndex, conf, 0)
if err != nil {
return errors.Wrapf(err, "cannot unconfigure policies on interface %d", swIfIndex)
Expand Down
15 changes: 2 additions & 13 deletions calico-vpp-agent/felix/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,6 @@ func fromProtoRule(r *proto.Rule) (rule *Rule, err error) {
return nil, fmt.Errorf("unknown rule action: %s", r.Action)
}

switch r.IpVersion {
case proto.IPVersion_ANY:
rule.AddressFamily = types.FamilyAll
case proto.IPVersion_IPV4:
rule.AddressFamily = types.FamilyV4
case proto.IPVersion_IPV6:
rule.AddressFamily = types.FamilyV6
default:
return nil, fmt.Errorf("unknown rule AF: %d", r.IpVersion)
}

if r.Protocol != nil {
if r.NotProtocol != nil {
return nil, fmt.Errorf("protocol and NotProtocol specified in Rule")
Expand All @@ -144,7 +133,7 @@ func fromProtoRule(r *proto.Rule) (rule *Rule, err error) {
}
rule.Filters = append(rule.Filters, types.RuleFilter{
ShouldMatch: true,
Type: types.CapoFilterProto,
Type: types.NpolFilterProto,
Value: int(proto),
})
}
Expand All @@ -155,7 +144,7 @@ func fromProtoRule(r *proto.Rule) (rule *Rule, err error) {
}
rule.Filters = append(rule.Filters, types.RuleFilter{
ShouldMatch: false,
Type: types.CapoFilterProto,
Type: types.NpolFilterProto,
Value: int(proto),
})
}
Expand Down
30 changes: 27 additions & 3 deletions calico-vpp-agent/felix/workload_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/projectcalico/calico/felix/proto"

"github.com/projectcalico/vpp-dataplane/v3/vpplink"
"github.com/projectcalico/vpp-dataplane/v3/vpplink/generated/bindings/npol"
"github.com/projectcalico/vpp-dataplane/v3/vpplink/types"
)

Expand Down Expand Up @@ -87,7 +88,7 @@ func fromProtoWorkload(wep *proto.WorkloadEndpoint, server *Server) *WorkloadEnd
return r
}

func (w *WorkloadEndpoint) getPolicies(state *PolicyState, network string) (conf *types.InterfaceConfig, err error) {
func (w *WorkloadEndpoint) getUserDefinedPolicies(state *PolicyState, network string) (conf *types.InterfaceConfig, err error) {
conf = types.NewInterfaceConfig()
for _, tier := range w.Tiers {
for _, polName := range tier.IngressPolicies {
Expand Down Expand Up @@ -121,14 +122,37 @@ func (w *WorkloadEndpoint) getPolicies(state *PolicyState, network string) (conf
}
conf.ProfileIDs = append(conf.ProfileIDs, prof.VppID)
}
return conf, nil
}

/*
This function creates the interface configuration for a workload (pod) interface
We have an implicit ingress policy that allows traffic coming from the host
see createAllowFromHostPolicy()
If there are no policies the default should be pass to profiles
If there are policies the default should be deny (profiles are ignored)
*/
func (w *WorkloadEndpoint) getWorkloadPolicies(state *PolicyState, network string) (conf *types.InterfaceConfig, err error) {
conf, err = w.getUserDefinedPolicies(state, network)
if err != nil {
return nil, errors.Wrap(err, "cannot create workload policies")
}
if len(conf.IngressPolicyIDs) > 0 {
conf.IngressPolicyIDs = append([]uint32{w.server.AllowFromHostPolicy.VppID}, conf.IngressPolicyIDs...)
conf.PolicyDefaultTx = npol.NPOL_DEFAULT_DENY
} else if len(conf.ProfileIDs) > 0 {
conf.PolicyDefaultTx = npol.NPOL_DEFAULT_PASS
}
if len(conf.EgressPolicyIDs) > 0 {
conf.PolicyDefaultRx = npol.NPOL_DEFAULT_DENY
} else if len(conf.ProfileIDs) > 0 {
conf.PolicyDefaultRx = npol.NPOL_DEFAULT_PASS
}
return conf, nil
}

func (w *WorkloadEndpoint) Create(vpp *vpplink.VppLink, swIfIndexes []uint32, state *PolicyState, network string) (err error) {
conf, err := w.getPolicies(state, network)
conf, err := w.getWorkloadPolicies(state, network)
if err != nil {
return err
}
Expand All @@ -144,7 +168,7 @@ func (w *WorkloadEndpoint) Create(vpp *vpplink.VppLink, swIfIndexes []uint32, st
}

func (w *WorkloadEndpoint) Update(vpp *vpplink.VppLink, new *WorkloadEndpoint, state *PolicyState, network string) (err error) {
conf, err := new.getPolicies(state, network)
conf, err := new.getWorkloadPolicies(state, network)
if err != nil {
return err
}
Expand Down
16 changes: 8 additions & 8 deletions cmd/calicovppctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,14 +398,14 @@ func exportData(k *KubeClient, nodeName string) error {
}
executeVppCommandGroup(k, exportDir, prefix, node, "Dumping node state", cnatCmds)

// Get CAPO policies
capoCmds := []CommandSpec{
{"show capo interfaces", node + ".show-capo-interfaces"},
{"show capo policies verbose", node + ".show-capo-policies"},
{"show capo rules", node + ".show-capo-rules"},
{"show capo ipsets", node + ".show-capo-ipsets"},
}
executeVppCommandGroup(k, exportDir, prefix, node, "Dumping node policies", capoCmds)
// Get NPOL policies
npolCmds := []CommandSpec{
{"show npol interfaces", node + ".show-npol-interfaces"},
{"show npol policies verbose", node + ".show-npol-policies"},
{"show npol rules", node + ".show-npol-rules"},
{"show npol ipsets", node + ".show-npol-ipsets"},
}
executeVppCommandGroup(k, exportDir, prefix, node, "Dumping node policies", npolCmds)
}

// Compress the temporary directory
Expand Down
Loading
Loading