Skip to content

Commit a472145

Browse files
committed
change capo to make default behavior configurable
This patch uses a vpp capo plugin patch that makes the default behavior when policies don't match configurable: drop, or goto profiles, depending on the existence of user defined policies This addresses the issue where dataplane takes wrong decisions because it isn't aware of the difference between a user defined policy and an implicit policy (like failsafe) This also prepends an explicit deny policy in the case of an empty hostendpoint (hep with 0 policies and 0 profiles). This also makes endpointtohost action prior to failsafe to comply with doc.
1 parent dba8b5c commit a472145

File tree

8 files changed

+99
-38
lines changed

8 files changed

+99
-38
lines changed

calico-vpp-agent/felix/felix_server.go

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,11 @@ type Server struct {
9090
allPodsIpset *IPSet
9191
/* allow traffic between uplink/tunnels and tap interfaces */
9292
allowToHostPolicy *Policy
93-
ip4 *net.IP
94-
ip6 *net.IP
95-
interfacesMap map[string]interfaceDetails
93+
/* deny all policy for heps with no policies defined */
94+
denyAllPolicy *Policy
95+
ip4 *net.IP
96+
ip6 *net.IP
97+
interfacesMap map[string]interfaceDetails
9698

9799
felixServerEventChan chan common.CalicoVppEvent
98100
networkDefinitions map[string]*watchers.NetworkDefinition
@@ -460,6 +462,10 @@ func (s *Server) ServeFelix(t *tomb.Tomb) error {
460462
if err != nil {
461463
return errors.Wrap(err, "Error in createFailSafePolicies")
462464
}
465+
err = s.createEmptyHEPDenyAllPolicy()
466+
if err != nil {
467+
return errors.Wrap(err, "Error in createFailSafePolicies")
468+
}
463469
for {
464470
s.state = StateDisconnected
465471
// Accept only one connection
@@ -1728,6 +1734,35 @@ func (s *Server) createEndpointToHostPolicy( /*may be return*/ ) (err error) {
17281734
return nil
17291735
}
17301736

1737+
func (s *Server) createEmptyHEPDenyAllPolicy() (err error) {
1738+
denyAllPol := &Policy{
1739+
Policy: &types.Policy{},
1740+
VppID: types.InvalidID,
1741+
InboundRules: []*Rule{
1742+
{
1743+
VppID: types.InvalidID,
1744+
Rule: &types.Rule{
1745+
Action: types.ActionDeny,
1746+
},
1747+
},
1748+
},
1749+
OutboundRules: []*Rule{
1750+
{
1751+
VppID: types.InvalidID,
1752+
Rule: &types.Rule{
1753+
Action: types.ActionDeny,
1754+
},
1755+
},
1756+
},
1757+
}
1758+
err = denyAllPol.Create(s.vpp, nil)
1759+
if err != nil {
1760+
return err
1761+
}
1762+
s.denyAllPolicy = denyAllPol
1763+
return nil
1764+
}
1765+
17311766
// createFailSafePolicies ensures the failsafe policies defined in the Felixconfiguration exist in VPP.
17321767
// check https://github.com/projectcalico/calico/blob/master/felix/rules/static.go :: failsafeInChain for the linux implementation
17331768
// To be noted. This does not implement the doNotTrack case as we do not yet support doNotTrack policies.

calico-vpp-agent/felix/host_endpoint.go

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func (h *HostEndpoint) handleTunnelChange(swIfIndex uint32, isAdd bool, pending
134134
return err
135135
}
136136

137-
func (h *HostEndpoint) getHostPolicies(state *PolicyState, tiers []Tier) (conf *types.InterfaceConfig, err error) {
137+
func (h *HostEndpoint) getUserDefinedPolicies(state *PolicyState, tiers []Tier) (conf *types.InterfaceConfig, err error) {
138138
conf = types.NewInterfaceConfig()
139139
for _, tier := range tiers {
140140
for _, polName := range tier.IngressPolicies {
@@ -172,31 +172,46 @@ func (h *HostEndpoint) getHostPolicies(state *PolicyState, tiers []Tier) (conf *
172172
}
173173

174174
func (h *HostEndpoint) getTapPolicies(state *PolicyState) (conf *types.InterfaceConfig, err error) {
175-
conf, err = h.getHostPolicies(state, h.Tiers)
175+
conf, err = h.getUserDefinedPolicies(state, h.Tiers)
176176
if err != nil {
177177
return nil, errors.Wrap(err, "cannot create host policies for TapConf")
178178
}
179-
if len(conf.IngressPolicyIDs) > 0 {
180-
conf.IngressPolicyIDs = append(conf.IngressPolicyIDs, h.server.workloadsToHostPolicy.VppID)
179+
if len(conf.IngressPolicyIDs) == 0 && len(conf.ProfileIDs) == 0 {
180+
// If a host endpoint is created and network policy is not in place,
181+
// the Calico default is to deny traffic to/from that endpoint
182+
// (except for traffic allowed by failsafe rules).
183+
conf.IngressPolicyIDs = []uint32{h.server.workloadsToHostPolicy.VppID, h.server.failSafePolicy.VppID, h.server.denyAllPolicy.VppID}
184+
} else {
185+
if len(conf.IngressPolicyIDs) > 0 {
186+
conf.UserDefinedTx = 1
187+
}
181188
conf.IngressPolicyIDs = append([]uint32{h.server.failSafePolicy.VppID}, conf.IngressPolicyIDs...)
189+
conf.IngressPolicyIDs = append([]uint32{h.server.workloadsToHostPolicy.VppID}, conf.IngressPolicyIDs...)
182190
}
183-
if len(conf.EgressPolicyIDs) > 0 {
184-
conf.EgressPolicyIDs = append([]uint32{h.server.AllowFromHostPolicy.VppID}, conf.EgressPolicyIDs...)
191+
if len(conf.EgressPolicyIDs) == 0 && len(conf.ProfileIDs) == 0 {
192+
conf.EgressPolicyIDs = []uint32{h.server.AllowFromHostPolicy.VppID, h.server.failSafePolicy.VppID, h.server.denyAllPolicy.VppID}
193+
} else {
194+
if len(conf.EgressPolicyIDs) > 0 {
195+
conf.UserDefinedRx = 1
196+
}
185197
conf.EgressPolicyIDs = append([]uint32{h.server.failSafePolicy.VppID}, conf.EgressPolicyIDs...)
198+
conf.EgressPolicyIDs = append([]uint32{h.server.AllowFromHostPolicy.VppID}, conf.EgressPolicyIDs...)
186199
}
187200
return conf, nil
188201
}
189202

190203
func (h *HostEndpoint) getForwardPolicies(state *PolicyState) (conf *types.InterfaceConfig, err error) {
191-
conf, err = h.getHostPolicies(state, h.ForwardTiers)
204+
conf, err = h.getUserDefinedPolicies(state, h.ForwardTiers)
192205
if err != nil {
193206
return nil, errors.Wrap(err, "cannot create host policies for forwardConf")
194207
}
195208
if len(conf.EgressPolicyIDs) > 0 {
196209
conf.EgressPolicyIDs = append([]uint32{h.server.allowToHostPolicy.VppID}, conf.EgressPolicyIDs...)
210+
conf.UserDefinedRx = 1
197211
}
198212
if len(conf.IngressPolicyIDs) > 0 {
199213
conf.IngressPolicyIDs = append([]uint32{h.server.allowToHostPolicy.VppID}, conf.IngressPolicyIDs...)
214+
conf.UserDefinedTx = 1
200215
}
201216
return conf, nil
202217
}

calico-vpp-agent/felix/workload_endpoint.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func fromProtoWorkload(wep *proto.WorkloadEndpoint, server *Server) *WorkloadEnd
8787
return r
8888
}
8989

90-
func (w *WorkloadEndpoint) getPolicies(state *PolicyState, network string) (conf *types.InterfaceConfig, err error) {
90+
func (w *WorkloadEndpoint) getUserDefinedPolicies(state *PolicyState, network string) (conf *types.InterfaceConfig, err error) {
9191
conf = types.NewInterfaceConfig()
9292
for _, tier := range w.Tiers {
9393
for _, polName := range tier.IngressPolicies {
@@ -121,14 +121,26 @@ func (w *WorkloadEndpoint) getPolicies(state *PolicyState, network string) (conf
121121
}
122122
conf.ProfileIDs = append(conf.ProfileIDs, prof.VppID)
123123
}
124+
return conf, nil
125+
}
126+
127+
func (w *WorkloadEndpoint) getWorkloadPolicies(state *PolicyState, network string) (conf *types.InterfaceConfig, err error) {
128+
conf, err = w.getUserDefinedPolicies(state, network)
129+
if err != nil {
130+
return nil, errors.Wrap(err, "cannot create workload policies")
131+
}
124132
if len(conf.IngressPolicyIDs) > 0 {
125133
conf.IngressPolicyIDs = append([]uint32{w.server.AllowFromHostPolicy.VppID}, conf.IngressPolicyIDs...)
134+
conf.UserDefinedTx = 1
135+
}
136+
if len(conf.EgressPolicyIDs) > 0 {
137+
conf.UserDefinedRx = 1
126138
}
127139
return conf, nil
128140
}
129141

130142
func (w *WorkloadEndpoint) Create(vpp *vpplink.VppLink, swIfIndexes []uint32, state *PolicyState, network string) (err error) {
131-
conf, err := w.getPolicies(state, network)
143+
conf, err := w.getWorkloadPolicies(state, network)
132144
if err != nil {
133145
return err
134146
}
@@ -144,7 +156,7 @@ func (w *WorkloadEndpoint) Create(vpp *vpplink.VppLink, swIfIndexes []uint32, st
144156
}
145157

146158
func (w *WorkloadEndpoint) Update(vpp *vpplink.VppLink, new *WorkloadEndpoint, state *PolicyState, network string) (err error) {
147-
conf, err := new.getPolicies(state, network)
159+
conf, err := new.getWorkloadPolicies(state, network)
148160
if err != nil {
149161
return err
150162
}

vpplink/capo.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ func (v *VppLink) ConfigurePolicies(swIfIndex uint32, conf *types.InterfaceConfi
206206
TotalIds: uint32(len(rxPolicyIDs) + len(txPolicyIDs) + len(profileIDs)),
207207
PolicyIds: ids,
208208
InvertRxTx: invertRxTx,
209+
UserDefinedRx: conf.UserDefinedRx,
210+
UserDefinedTx: conf.UserDefinedTx,
209211
})
210212
if err != nil {
211213
return fmt.Errorf("capoConfigurePolicies failed: %w", err)

vpplink/generated/bindings/capo/capo.ba.go

Lines changed: 11 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vpplink/generated/generate.log

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,13 @@
1-
VPP Version : 25.06.0-19~g354a6aabf
1+
VPP Version : 25.06-rc0~248-gfaaad85cd
22
Binapi-generator version : v0.11.0
3-
VPP Base commit : 47505bc21 misc: Initial changes for stable/2506 branch
3+
VPP Base commit : 91a65d8a5 gerrit:34726/3 interface: add buffer stats api
44
------------------ Cherry picked commits --------------------
5+
gerrit:43468/5 capo: fix default behavior and add user defined policy flag
6+
ip: add support for checksum in IP midchain
57
capo: Calico Policies plugin
68
acl: acl-plugin custom policies
79
cnat: [WIP] no k8s maglev from pods
810
pbl: Port based balancer
9-
gerrit:42876/10 gso: add support for ipip tso for phyiscal interfaces
10-
gerrit:42598/12 pg: add support for checksum offload
11-
gerrit:43336/3 gso: fix ip fragment support for gso packet
12-
gerrit:42425/8 interface: add support for proper checksum handling
13-
gerrit:43083/3 virtio: conditionally set checksum offload based on TCP/UDP offload flags
14-
gerrit:43084/3 af_packet: conditionally set checksum offload based on TCP/UDP offload flags
15-
gerrit:43082/6 ipip: fix the offload flags
16-
gerrit:42891/5 ip: compute checksums before fragmentation if offloaded
17-
gerrit:43081/2 interface: clear flags after checksum computation
18-
gerrit:42419/5 dpdk: fix the outer flags
19-
gerrit:42186/6 tap: enable IPv4 checksum offload on interface
20-
gerrit:42185/6 vnet: add assert for offload flags in debug mode
21-
gerrit:42184/6 interface: add a new cap for virtual interfaces
2211
gerrit:revert:39675/5 Revert "ip-neighbor: do not use sas to determine NS source address"
2312
gerrit:34726/3 interface: add buffer stats api
24-
misc: VPP 25.06 Release Notes
25-
hsa: http client init wrk->vlib_main in setup
26-
tls: add half close support
27-
af_packet: show host interface offload flags
28-
af_packet: fix the error handling on transmit
29-
dma_intel: fix ats_disable attribute handling
30-
misc: Initial changes for stable/2506 branch
3113
-------------------------------------------------------------

vpplink/generated/vpp_clone_current.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,6 @@ git_apply_private 0001-pbl-Port-based-balancer.patch
146146
git_apply_private 0002-cnat-WIP-no-k8s-maglev-from-pods.patch
147147
git_apply_private 0003-acl-acl-plugin-custom-policies.patch
148148
git_apply_private 0004-capo-Calico-Policies-plugin.patch
149+
150+
151+
git_cherry_pick refs/changes/68/43468/5 https://gerrit.fd.io/r/c/vpp/+/43468

vpplink/types/capo.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,13 +326,17 @@ type InterfaceConfig struct {
326326
IngressPolicyIDs []uint32
327327
EgressPolicyIDs []uint32
328328
ProfileIDs []uint32
329+
UserDefinedRx uint8
330+
UserDefinedTx uint8
329331
}
330332

331333
func NewInterfaceConfig() *InterfaceConfig {
332334
return &InterfaceConfig{
333335
IngressPolicyIDs: make([]uint32, 0),
334336
EgressPolicyIDs: make([]uint32, 0),
335337
ProfileIDs: make([]uint32, 0),
338+
UserDefinedRx: 0,
339+
UserDefinedTx: 0,
336340
}
337341
}
338342

0 commit comments

Comments
 (0)